/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Stephan Herrmann - Contribution for
 *								Bug 458577 - IClassFile.getWorkingCopy() may lead to NPE in BecomeWorkingCopyOperation
 *								Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
 *								Bug 462768 - [null] NPE when using linked folder for external annotations
 *******************************************************************************/
package org.eclipse.jdt.internal.core;

import java.io.File;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.core.util.Util;

/**
 * Common parts of ClassFile (containing a BinaryType) and ModularClassFile (containing a BinaryModule).
 * Prior to Java 9, most of this content was directly in ClassFile.
 */
public abstract class AbstractClassFile extends Openable implements IClassFile, SuffixConstants {

	protected String name;

	protected AbstractClassFile(PackageFragment parent, String nameWithoutExtension) {
		super(parent);
		this.name = nameWithoutExtension;
	}

	/*
	 * @see IClassFile#becomeWorkingCopy(IProblemRequestor, WorkingCopyOwner, IProgressMonitor)
	 */
	@Override
	public ICompilationUnit becomeWorkingCopy(IProblemRequestor problemRequestor, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
		JavaModelManager manager = JavaModelManager.getJavaModelManager();
		CompilationUnit workingCopy = new ClassFileWorkingCopy(this, owner == null ? DefaultWorkingCopyOwner.PRIMARY : owner);
		JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(workingCopy, false/*don't create*/, true /*record usage*/, null/*no problem requestor needed*/);
		if (perWorkingCopyInfo == null) {
			// close cu and its children
			close();
	
			BecomeWorkingCopyOperation operation = new BecomeWorkingCopyOperation(workingCopy, problemRequestor);
			operation.runOperation(monitor);
	
			return workingCopy;
		}
		return perWorkingCopyInfo.workingCopy;
	}

	/**
	 * @see ICodeAssist#codeComplete(int, ICompletionRequestor)
	 * @deprecated
	 */
	@Override
	@Deprecated
	public void codeComplete(int offset, ICompletionRequestor requestor) throws JavaModelException {
		codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
	}
	/**
	 * @see ICodeAssist#codeComplete(int, ICompletionRequestor, WorkingCopyOwner)
	 * @deprecated
	 */
	@Override
	@Deprecated
	public void codeComplete(int offset, ICompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
		if (requestor == null) {
			throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
		}
		codeComplete(offset, new org.eclipse.jdt.internal.codeassist.CompletionRequestorWrapper(requestor), owner);
	}

	@Override
	public void codeComplete(int offset, CompletionRequestor requestor) throws JavaModelException {
		codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
	}

	@Override
	public void codeComplete(int offset, CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
		codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY, monitor);
	}

	@Override
	public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
		codeComplete(offset, requestor, owner, null);
	}
	@Override
	public abstract void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException;
	
	/**
	 * @see ICodeAssist#codeSelect(int, int)
	 */
	@Override
	public IJavaElement[] codeSelect(int offset, int length) throws JavaModelException {
		return codeSelect(offset, length, DefaultWorkingCopyOwner.PRIMARY);
	}
	@Override
	public abstract IJavaElement[] codeSelect(int offset, int length, WorkingCopyOwner owner) throws JavaModelException;
	
	/**
	 * Returns a new element info for this element.
	 */
	@Override
	protected Object createElementInfo() {
		return new ClassFileInfo();
	}
	@Override
	public boolean equals(Object o) {
		if (!(o instanceof AbstractClassFile)) return false;
		AbstractClassFile other = (AbstractClassFile) o;
		return this.name.equals(other.name) && this.parent.equals(other.parent);
	}
	
	/**
	 * Finds the deepest <code>IJavaElement</code> in the hierarchy of
	 * <code>elt</elt>'s children (including <code>elt</code> itself)
	 * which has a source range that encloses <code>position</code>
	 * according to <code>mapper</code>.
	 */
	protected IJavaElement findElement(IJavaElement elt, int position, SourceMapper mapper) {
		SourceRange range = mapper.getSourceRange(elt);
		if (range == null || position < range.getOffset() || range.getOffset() + range.getLength() - 1 < position) {
			return null;
		}
		if (elt instanceof IParent) {
			try {
				IJavaElement[] children = ((IParent) elt).getChildren();
				for (int i = 0; i < children.length; i++) {
					IJavaElement match = findElement(children[i], position, mapper);
					if (match != null) {
						return match;
					}
				}
			} catch (JavaModelException npe) {
				// elt doesn't exist: return the element
			}
		}
		return elt;
	}
	
	@Override
	public byte[] getBytes() throws JavaModelException {
		JavaElement pkg = (JavaElement) getParent();
		if (pkg instanceof JarPackageFragment) {
			JarPackageFragmentRoot root = (JarPackageFragmentRoot) pkg.getParent();
			try {
				String entryName = Util.concatWith(((PackageFragment) pkg).names, getElementName(), '/');
				entryName = root.getClassFilePath(entryName);
				return getClassFileContent(root, entryName);
				// Java 9 - The below exception is not thrown in new scheme of things. Could cause issues?
	//			throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this));
			} catch (IOException ioe) {
				throw new JavaModelException(ioe, IJavaModelStatusConstants.IO_EXCEPTION);
			} catch (CoreException e) {
				if (e instanceof JavaModelException) {
					throw (JavaModelException)e;
				} else {
					throw new JavaModelException(e);
				}
			}
		} else {
			IFile file = (IFile) resource();
			return Util.getResourceContentsAsByteArray(file);
		}
	}
	protected byte[] getClassFileContent(JarPackageFragmentRoot root, String className) throws CoreException, IOException {
		byte[] contents = null;
		String rootPath = root.getPath().toOSString();
		if (root instanceof JrtPackageFragmentRoot) {
				try {
					contents = org.eclipse.jdt.internal.compiler.util.JRTUtil.getClassfileContent(
							new File(rootPath),
							className,
							root.getElementName());
				} catch (ClassFormatException e) {
					e.printStackTrace();
				}
		} else {
			ZipFile zip = root.getJar();
			try {
				ZipEntry ze = zip.getEntry(className);
				if (ze != null) {
					contents = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip);
				}
			} finally {
				JavaModelManager.getJavaModelManager().closeZipFile(zip);
			}
		}
		return contents;
	}
	
	@Override
	public IBuffer getBuffer() throws JavaModelException {
		IStatus status = validateClassFile();
		if (status.isOK()) {
			return super.getBuffer();
		} else {
			switch (status.getCode()) {
			case IJavaModelStatusConstants.ELEMENT_NOT_ON_CLASSPATH: // don't throw a JavaModelException to be able to open .class file outside the classpath (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=138507 )
			case IJavaModelStatusConstants.INVALID_ELEMENT_TYPES: // don't throw a JavaModelException to be able to open .class file in proj==src case without source (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=221904 )
				return null;
			default:
				throw new JavaModelException(status);
			}
		}
	}
	/**
	 * @see IMember#getTypeRoot()
	 */
	public ITypeRoot getTypeRoot() {
		return this;
	}
	
	/**
	 * A class file has a corresponding resource unless it is contained
	 * in a jar.
	 *
	 * @see IJavaElement
	 */
	@Override
	public IResource getCorrespondingResource() throws JavaModelException {
		IPackageFragmentRoot root= (IPackageFragmentRoot)getParent().getParent();
		if (root.isArchive()) {
			return null;
		} else {
			return getUnderlyingResource();
		}
	}
	public IJavaElement getElementAtConsideringSibling(int position) throws JavaModelException {
		IPackageFragment fragment = (IPackageFragment)getParent();
		PackageFragmentRoot root = (PackageFragmentRoot) fragment.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
		SourceMapper mapper = root.getSourceMapper();
		if (mapper == null) {
			return null;
		} else {
			int index = this.name.indexOf('$');
			int prefixLength = index < 0 ? this.name.length() : index;
	
			IType type = null;
			int start = -1;
			int end = Integer.MAX_VALUE;
			IJavaElement[] children = fragment.getChildren();
			for (int i = 0; i < children.length; i++) {
				if (children[i] instanceof IOrdinaryClassFile) {
					IOrdinaryClassFile classFile = (IOrdinaryClassFile) children[i];
					String childName = classFile.getElementName();
		
					int childIndex = childName.indexOf('$');
					int childPrefixLength = childIndex < 0 ? childName.indexOf('.') : childIndex;
					if (prefixLength == childPrefixLength && this.name.regionMatches(0, childName, 0, prefixLength)) {
		
						// ensure this class file's buffer is open so that source ranges are computed
						classFile.getBuffer();
		
						SourceRange range = mapper.getSourceRange(classFile.getType());
						if (range == SourceMapper.UNKNOWN_RANGE) continue;
						int newStart = range.getOffset();
						int newEnd = newStart + range.getLength() - 1;
						if(newStart > start && newEnd < end
								&& newStart <= position && newEnd >= position) {
							type = classFile.getType();
							start = newStart;
							end = newEnd;
						}
					}
				}
			}
			if(type != null) {
				return findElement(type, position, mapper);
			}
			return null;
		}
	}
	@Override
	public String getElementName() {
		return this.name + SuffixConstants.SUFFIX_STRING_class;
	}
	/**
	 * @see IJavaElement
	 */
	@Override
	public int getElementType() {
		return CLASS_FILE;
	}

	/*
	 * @see IJavaElement
	 */
	@Override
	public IPath getPath() {
		PackageFragmentRoot root = getPackageFragmentRoot();
		if (root.isArchive()) {
			return root.getPath();
		} else {
			return getParent().getPath().append(getElementName());
		}
	}
	
	/*
	 * @see IJavaElement
	 */
	@Override
	public IResource resource(PackageFragmentRoot root) {
		return ((IContainer) ((Openable) this.parent).resource(root)).getFile(new Path(getElementName()));
	}
	/**
	 * @see ISourceReference
	 */
	@Override
	public String getSource() throws JavaModelException {
		IBuffer buffer = getBuffer();
		if (buffer == null) {
			return null;
		}
		return buffer.getContents();
	}
	/**
	 * @see ISourceReference
	 */
	@Override
	public ISourceRange getSourceRange() throws JavaModelException {
		IBuffer buffer = getBuffer();
		if (buffer != null) {
			String contents = buffer.getContents();
			if (contents == null) return null;
			return new SourceRange(0, contents.length());
		} else {
			return null;
		}
	}
	/**
	 * @see IClassFile
	 * @deprecated
	 */
	@Override
	@Deprecated
	public IJavaElement getWorkingCopy(IProgressMonitor monitor, org.eclipse.jdt.core.IBufferFactory factory) throws JavaModelException {
		return getWorkingCopy(BufferFactoryWrapper.create(factory), monitor);
	}
	/**
	 * @see Openable
	 */
	@Override
	protected boolean hasBuffer() {
		return true;
	}
	@Override
	public int hashCode() {
		return Util.combineHashCodes(this.name.hashCode(), this.parent.hashCode());
	}
	/**
	 * Returns true - class files are always read only.
	 */
	@Override
	public boolean isReadOnly() {
		return true;
	}
	private IStatus validateClassFile() {
		IPackageFragmentRoot root = getPackageFragmentRoot();
		try {
			if (root.getKind() != IPackageFragmentRoot.K_BINARY)
				return new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, root);
		} catch (JavaModelException e) {
			return e.getJavaModelStatus();
		}
		IJavaProject project = getJavaProject();
		return JavaConventions.validateClassFileName(getElementName(), project.getOption(JavaCore.COMPILER_SOURCE, true), project.getOption(JavaCore.COMPILER_COMPLIANCE, true));
	}
	

	/**
	 * @see ICodeAssist#codeComplete(int, ICodeCompletionRequestor)
	 * @deprecated - should use codeComplete(int, ICompletionRequestor) instead
	 */
	@Override
	@Deprecated
	public void codeComplete(int offset, final org.eclipse.jdt.core.ICodeCompletionRequestor requestor) throws JavaModelException {

		if (requestor == null){
			codeComplete(offset, (ICompletionRequestor)null);
			return;
		}
		codeComplete(
			offset,
			new ICompletionRequestor(){
				@Override
				public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName, char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
					// ignore
				}
				@Override
				public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
					requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
				}
				@Override
				public void acceptError(IProblem error) {
					// was disabled in 1.0
				}
				@Override
				public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] fieldName, char[] typePackageName, char[] typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
					requestor.acceptField(declaringTypePackageName, declaringTypeName, fieldName, typePackageName, typeName, completionName, modifiers, completionStart, completionEnd);
				}
				@Override
				public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
					requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
				}
				@Override
				public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
					requestor.acceptKeyword(keywordName, completionStart, completionEnd);
				}
				@Override
				public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
					requestor.acceptLabel(labelName, completionStart, completionEnd);
				}
				@Override
				public void acceptLocalVariable(char[] localVarName,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int completionEnd, int relevance){
					// ignore
				}
				@Override
				public void acceptMethod(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
					// skip parameter names
					requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames, returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
				}
				@Override
				public void acceptMethodDeclaration(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
					// ignore
				}
				@Override
				public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
					requestor.acceptModifier(modifierName, completionStart, completionEnd);
				}
				@Override
				public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
					requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
				}
				@Override
				public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int relevance){
					requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
				}
				@Override
				public void acceptVariableName(char[] typePackageName,char[] typeName,char[] varName,char[] completionName,int completionStart,int completionEnd, int relevance){
					// ignore
				}
			});
	}
	
	@Override
	protected IStatus validateExistence(IResource underlyingResource) {
		// check whether the class file can be opened
		IStatus status = validateClassFile();
		if (!status.isOK())
			return status;
		if (underlyingResource != null) {
			if (!underlyingResource.isAccessible())
				return newDoesNotExistStatus();
			PackageFragmentRoot root;
			if ((underlyingResource instanceof IFolder) && (root = getPackageFragmentRoot()).isArchive()) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=204652
				return root.newDoesNotExistStatus();
			}
		}
		return JavaModelStatus.VERIFIED_OK;
	}
	
	@Override
	public ISourceRange getNameRange() {
		return null;
	}
}
