/*******************************************************************************
 * Copyright (c) 2005, 2017 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.core;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.dltk.compiler.CharOperation;
import org.eclipse.dltk.core.CompletionRequestor;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.DLTKLanguageManager;
import org.eclipse.dltk.core.IField;
import org.eclipse.dltk.core.IMethod;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ITypeHierarchy;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.WorkingCopyOwner;
import org.eclipse.dltk.core.search.IDLTKSearchScope;
import org.eclipse.dltk.core.search.SearchEngine;
import org.eclipse.dltk.internal.core.hierarchy.TypeHierarchy;
import org.eclipse.dltk.internal.core.hierarchy.TypeHierarchyBuilders;
import org.eclipse.dltk.internal.core.util.MementoTokenizer;
import org.eclipse.dltk.internal.core.util.Messages;
import org.eclipse.dltk.utils.CorePrinter;

public class SourceType extends NamedMember implements IType {

	public SourceType(ModelElement parent, String name) {
		super(parent, name);
	}

	@Override
	public int getElementType() {
		return TYPE;
	}

	@Override
	public boolean equals(Object o) {
		if (!(o instanceof SourceType)) {
			return false;
		}
		return super.equals(o);
	}

	@Override
	public String[] getSuperClasses() throws ModelException {
		SourceTypeElementInfo info = (SourceTypeElementInfo) this
				.getElementInfo();
		if (info == null) {
			return CharOperation.NO_STRINGS;
		}
		return info.superclassNames;
	}

	@Override
	public void printNode(CorePrinter output) {
		output.formatPrint("DLTK Source Type:" + getElementName()); //$NON-NLS-1$
		output.indent();
		try {
			IModelElement modelElements[] = this.getChildren();
			for (int i = 0; i < modelElements.length; ++i) {
				IModelElement element = modelElements[i];
				if (element instanceof ModelElement) {
					((ModelElement) element).printNode(output);
				} else {
					output.print("Unknown element:" + element); //$NON-NLS-1$
				}
			}
		} catch (ModelException ex) {
			output.formatPrint(ex.getLocalizedMessage());
		}
		output.dedent();
	}

	@Override
	public IField getField(String fieldName) {
		return new SourceField(this, fieldName);
	}

	@Override
	public IField[] getFields() throws ModelException {
		List<IModelElement> list = getChildrenOfType(FIELD);
		IField[] array = new IField[list.size()];
		list.toArray(array);
		return array;
	}

	@Override
	public IType getType(String typeName) {
		return new SourceType(this, typeName);
	}

	@Override
	public IType[] getTypes() throws ModelException {
		List<IModelElement> list = getChildrenOfType(TYPE);
		IType[] array = new IType[list.size()];
		list.toArray(array);
		return array;
	}

	@Override
	public IMethod getMethod(String selector) {
		return new SourceMethod(this, selector);
	}

	@Override
	public IMethod[] getMethods() throws ModelException {
		List<IModelElement> list = getChildrenOfType(METHOD);
		IMethod[] array = new IMethod[list.size()];
		list.toArray(array);
		return array;
	}

	@Override
	public IModelElement getHandleFromMemento(String token,
			MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
		switch (token.charAt(0)) {
		case JEM_COUNT:
			return getHandleUpdatingCountFromMemento(memento, workingCopyOwner);
		case JEM_FIELD:
			if (!memento.hasMoreTokens()) {
				return this;
			}
			String fieldName = memento.nextToken();
			ModelElement field = (ModelElement) getField(fieldName);
			return field.getHandleFromMemento(memento, workingCopyOwner);
		// case JEM_INITIALIZER:
		// if (!memento.hasMoreTokens()) return this;
		// String count = memento.nextToken();
		// JavaElement initializer =
		// (JavaElement)getInitializer(Integer.parseInt(count));
		// return initializer.getHandleFromMemento(memento,
		// workingCopyOwner);
		case JEM_METHOD:
			if (!memento.hasMoreTokens()) {
				return this;
			}

			String selector = memento.nextToken();
			ArrayList<String> params = new ArrayList<>();
			nextParam: while (memento.hasMoreTokens()) {
				token = memento.nextToken();
				switch (token.charAt(0)) {
				case JEM_TYPE:
				case JEM_TYPE_PARAMETER:
					break nextParam;
				case JEM_METHOD:
					if (!memento.hasMoreTokens()) {
						return this;
					}

					String param = memento.nextToken();
					StringBuffer buffer = new StringBuffer();

					// backward compatible with 3.0 mementos
					/*
					 * while (param.length() == 1 && Signature.C_ARRAY ==
					 * param.charAt(0)) { buffer.append(Signature.C_ARRAY); if
					 * (!memento.hasMoreTokens()) return this; param =
					 * memento.nextToken(); }
					 */

					params.add(buffer.toString() + param);
					break;
				default:
					break nextParam;
				}
			}
			String[] parameters = new String[params.size()];
			params.toArray(parameters);
			ModelElement method = (ModelElement) getMethod(selector);
			switch (token.charAt(0)) {
			case JEM_TYPE:
			case JEM_TYPE_PARAMETER:
			case JEM_LOCALVARIABLE:
				return method.getHandleFromMemento(token, memento,
						workingCopyOwner);
			default:
				return method;
			}
		case JEM_TYPE:
			String typeName;
			if (memento.hasMoreTokens()) {
				typeName = memento.nextToken();
				char firstChar = typeName.charAt(0);
				if (firstChar == JEM_FIELD /* || firstChar == JEM_INITIALIZER */
						|| firstChar == JEM_METHOD || firstChar == JEM_TYPE
						|| firstChar == JEM_COUNT) {
					token = typeName;
					typeName = ""; //$NON-NLS-1$
				} else {
					token = null;
				}
			} else {
				typeName = ""; //$NON-NLS-1$
				token = null;
			}
			ModelElement type = (ModelElement) getType(typeName);
			if (token == null) {
				return type.getHandleFromMemento(memento, workingCopyOwner);
			} else {
				return type.getHandleFromMemento(token, memento,
						workingCopyOwner);
			}
			// case JEM_TYPE_PARAMETER:
			// if (!memento.hasMoreTokens()) return this;
			// String typeParameterName = memento.nextToken();
			// ModelElement typeParameter = new TypeParameter(this,
			// typeParameterName);
			// return typeParameter.getHandleFromMemento(memento,
			// workingCopyOwner);

		}
		return null;
	}

	@Override
	protected char getHandleMementoDelimiter() {

		return JEM_TYPE;
	}

	@Override
	public String getFullyQualifiedName(String enclosingTypeSeparator) {
		try {
			return getFullyQualifiedName(enclosingTypeSeparator,
					false/*
							 * don't show parameters
							 */);
		} catch (ModelException e) {
			// exception thrown only when showing parameters
			return null;
		}
	}

	@Override
	public String getFullyQualifiedName() {
		return getFullyQualifiedName("$"); //$NON-NLS-1$
	}

	@Override
	public void codeComplete(char[] snippet, int insertion, int position,
			char[][] localVariableTypeNames, char[][] localVariableNames,
			int[] localVariableModifiers, boolean isStatic,
			CompletionRequestor requestor) throws ModelException {
		// TODO Auto-generated method stub

	}

	@Override
	public void codeComplete(char[] snippet, int insertion, int position,
			char[][] localVariableTypeNames, char[][] localVariableNames,
			int[] localVariableModifiers, boolean isStatic,
			CompletionRequestor requestor, WorkingCopyOwner owner)
			throws ModelException {
		// TODO Auto-generated method stub

	}

	@Override
	public IScriptFolder getScriptFolder() {
		IModelElement parentElement = this.parent;
		while (parentElement != null) {
			if (parentElement.getElementType() == IModelElement.SCRIPT_FOLDER) {
				return (IScriptFolder) parentElement;
			} else {
				parentElement = parentElement.getParent();
			}
		}
		Assert.isTrue(false); // should not happen
		return null;
	}

	/**
	 * @see IType#getTypeQualifiedName()
	 */
	@Override
	public String getTypeQualifiedName() {
		return this.getTypeQualifiedName("$"); //$NON-NLS-1$
	}

	/**
	 * @see IType#getTypeQualifiedName(char)
	 */
	@Override
	public String getTypeQualifiedName(String enclosingTypeSeparator) {
		try {
			return getTypeQualifiedName(enclosingTypeSeparator,
					false/*
							 * don't show parameters
							 */);
		} catch (ModelException e) {
			// exception thrown only when showing parameters
			return null;
		}
	}

	/*
	 * @see IType
	 */
	@Override
	public IMethod[] findMethods(IMethod method) {
		try {
			return findMethods(method, getMethods());
		} catch (ModelException e) {
			// if type doesn't exist, no matching method can exist
			return null;
		}
	}

	/*
	 * Type hierarchies section
	 */

	/**
	 * @see IType
	 */
	@Override
	public ITypeHierarchy loadTypeHierachy(InputStream input,
			IProgressMonitor monitor) throws ModelException {
		return loadTypeHierachy(input, DefaultWorkingCopyOwner.PRIMARY,
				monitor);
	}

	/**
	 * NOTE: This method is not part of the API has it is not clear clients
	 * would easily use it: they would need to first make sure all working
	 * copies for the given owner exist before calling it. This is especially
	 * har at startup time. In case clients want this API, here is how it should
	 * be specified:
	 * <p>
	 * Loads a previously saved ITypeHierarchy from an input stream. A type
	 * hierarchy can be stored using ITypeHierachy#store(OutputStream). A
	 * compilation unit of a loaded type has the given owner if such a working
	 * copy exists, otherwise the type's compilation unit is a primary
	 * compilation unit.
	 *
	 * Only hierarchies originally created by the following methods can be
	 * loaded:
	 * <ul>
	 * <li>IType#newSupertypeHierarchy(IProgressMonitor)</li>
	 * <li>IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
	 * <li>IType#newTypeHierarchy(IJavaProject, IProgressMonitor)</li>
	 * <li>IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner,
	 * IProgressMonitor)</li>
	 * <li>IType#newTypeHierarchy(IProgressMonitor)</li>
	 * <li>IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li> </u>
	 *
	 * @param input
	 *            stream where hierarchy will be read
	 * @param monitor
	 *            the given progress monitor
	 * @return the stored hierarchy
	 * @exception JavaModelException
	 *                if the hierarchy could not be restored, reasons include: -
	 *                type is not the focus of the hierarchy or - unable to read
	 *                the input stream (wrong format, IOException during
	 *                reading, ...)
	 * @see ITypeHierarchy#store(java.io.OutputStream, IProgressMonitor)
	 * @since 3.0
	 */
	public ITypeHierarchy loadTypeHierachy(InputStream input,
			WorkingCopyOwner owner, IProgressMonitor monitor)
			throws ModelException {
		// TODO monitor should be passed to TypeHierarchy.load(...)
		return TypeHierarchy.load(this, input, owner);
	}

	/**
	 * @see IType
	 */
	@Override
	public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor)
			throws ModelException {
		return this.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY,
				monitor);
	}

	/*
	 * @see IType#newSupertypeHierarchy(ICompilationUnit[], IProgressMonitor)
	 */
	@Override
	public ITypeHierarchy newSupertypeHierarchy(ISourceModule[] workingCopies,
			IProgressMonitor monitor) throws ModelException {

		CreateTypeHierarchyOperation op;
		IScriptProject scriptProject = getScriptProject();
		IDLTKSearchScope scope = SearchEngine.createSearchScope(scriptProject);
		op = new CreateTypeHierarchyOperation(this, workingCopies, scope,
				false);
		op.runOperation(monitor);
		return op.getResult();
	}

	/**
	 * @see IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)
	 */
	@Override
	public ITypeHierarchy newSupertypeHierarchy(WorkingCopyOwner owner,
			IProgressMonitor monitor) throws ModelException {
		final ITypeHierarchy hierarchy = TypeHierarchyBuilders
				.getTypeHierarchy(this, ITypeHierarchy.Mode.SUPERTYPE, monitor);
		if (hierarchy != null) {
			return hierarchy;
		}

		ISourceModule[] workingCopies = ModelManager.getModelManager()
				.getWorkingCopies(owner, true/* add primary working copies */);
		CreateTypeHierarchyOperation op;
		IScriptProject scriptProject = getScriptProject();
		IDLTKSearchScope scope = SearchEngine.createSearchScope(scriptProject);
		op = new CreateTypeHierarchyOperation(this, workingCopies, scope,
				false);
		op.runOperation(monitor);
		return op.getResult();
	}

	/**
	 * @see IType
	 */
	@Override
	public ITypeHierarchy newTypeHierarchy(IScriptProject project,
			IProgressMonitor monitor) throws ModelException {
		return newTypeHierarchy(project, DefaultWorkingCopyOwner.PRIMARY,
				monitor);
	}

	/**
	 * @see IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner,
	 *      IProgressMonitor)
	 */
	@Override
	public ITypeHierarchy newTypeHierarchy(IScriptProject project,
			WorkingCopyOwner owner, IProgressMonitor monitor)
			throws ModelException {
		if (project == null) {
			throw new IllegalArgumentException(Messages.hierarchy_nullProject);
		}
		ISourceModule[] workingCopies = ModelManager.getModelManager()
				.getWorkingCopies(owner, true/* add primary working copies */);
		ISourceModule[] projectWCs = null;
		if (workingCopies != null) {
			int length = workingCopies.length;
			projectWCs = new ISourceModule[length];
			int index = 0;
			for (int i = 0; i < length; i++) {
				ISourceModule wc = workingCopies[i];
				if (project.equals(wc.getScriptProject())) {
					projectWCs[index++] = wc;
				}
			}
			if (index != length) {
				System.arraycopy(projectWCs, 0,
						projectWCs = new ISourceModule[index], 0, index);
			}
		}
		CreateTypeHierarchyOperation op = new CreateTypeHierarchyOperation(this,
				projectWCs, project, true);
		op.runOperation(monitor);
		return op.getResult();
	}

	private IDLTKSearchScope createReferencingProjectsScope() {

		IScriptProject scriptProject = getScriptProject();
		IProject project = scriptProject.getProject();
		IProject[] referencingProjects = project.getReferencingProjects();

		List<IScriptProject> scriptProjects = new ArrayList<>(
				referencingProjects.length + 1);
		scriptProjects.add(scriptProject);

		for (int i = 0; i < referencingProjects.length; ++i) {
			IProject p = referencingProjects[i];
			if (p.isAccessible()) {
				scriptProjects.add(DLTKCore.create(p));
			}
		}
		return SearchEngine.createSearchScope(
				scriptProjects
						.toArray(new IModelElement[scriptProjects.size()]),
				false, DLTKLanguageManager.getLanguageToolkit(this));
	}

	/**
	 * @see IType
	 */
	@Override
	public ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor)
			throws ModelException {
		final ITypeHierarchy hierarchy = TypeHierarchyBuilders
				.getTypeHierarchy(this, ITypeHierarchy.Mode.HIERARCHY, monitor);
		if (hierarchy != null) {
			return hierarchy;
		}
		CreateTypeHierarchyOperation op;
		op = new CreateTypeHierarchyOperation(this, null,
				createReferencingProjectsScope(), true);
		op.runOperation(monitor);
		return op.getResult();
	}

	/*
	 * @see IType#newTypeHierarchy(ICompilationUnit[], IProgressMonitor)
	 */
	@Override
	public ITypeHierarchy newTypeHierarchy(ISourceModule[] workingCopies,
			IProgressMonitor monitor) throws ModelException {

		CreateTypeHierarchyOperation op;
		op = new CreateTypeHierarchyOperation(this, workingCopies,
				createReferencingProjectsScope(), true);
		op.runOperation(monitor);
		return op.getResult();
	}

	/**
	 * @see IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)
	 */
	@Override
	public ITypeHierarchy newTypeHierarchy(WorkingCopyOwner owner,
			IProgressMonitor monitor) throws ModelException {

		ISourceModule[] workingCopies = ModelManager.getModelManager()
				.getWorkingCopies(owner, true/* add primary working copies */);
		CreateTypeHierarchyOperation op;
		op = new CreateTypeHierarchyOperation(this, workingCopies,
				createReferencingProjectsScope(), true);
		op.runOperation(monitor);
		return op.getResult();
	}
}
