/*******************************************************************************
 * Copyright (c) 2000, 2008 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
 *******************************************************************************/
package org.eclipse.wst.jsdt.internal.corext.codemanipulation;

import java.util.ArrayList;

import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.wst.jsdt.core.Flags;
import org.eclipse.wst.jsdt.core.IBuffer;
import org.eclipse.wst.jsdt.core.IJavaScriptElement;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.JavaScriptModelException;
import org.eclipse.wst.jsdt.core.Signature;
import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.FunctionInvocation;
import org.eclipse.wst.jsdt.core.dom.IBinding;
import org.eclipse.wst.jsdt.core.dom.IFunctionBinding;
import org.eclipse.wst.jsdt.core.dom.ITypeBinding;
import org.eclipse.wst.jsdt.core.dom.IVariableBinding;
import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit;
import org.eclipse.wst.jsdt.core.dom.Modifier;
import org.eclipse.wst.jsdt.core.dom.Name;
import org.eclipse.wst.jsdt.core.dom.QualifiedName;
import org.eclipse.wst.jsdt.core.dom.QualifiedType;
import org.eclipse.wst.jsdt.core.dom.SimpleName;
import org.eclipse.wst.jsdt.core.dom.Type;
import org.eclipse.wst.jsdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.wst.jsdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchConstants;
import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchScope;
import org.eclipse.wst.jsdt.core.search.SearchEngine;
import org.eclipse.wst.jsdt.core.search.SearchPattern;
import org.eclipse.wst.jsdt.core.search.TypeNameMatch;
import org.eclipse.wst.jsdt.internal.corext.dom.ASTNodes;
import org.eclipse.wst.jsdt.internal.corext.dom.NodeFinder;
import org.eclipse.wst.jsdt.internal.corext.util.JavaModelUtil;
import org.eclipse.wst.jsdt.internal.corext.util.Messages;
import org.eclipse.wst.jsdt.internal.corext.util.TypeNameMatchCollector;
import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin;
import org.eclipse.wst.jsdt.internal.ui.JavaUIStatus;
import org.eclipse.wst.jsdt.internal.ui.javaeditor.ASTProvider;
import org.eclipse.wst.jsdt.internal.ui.text.correction.ASTResolving;
import org.eclipse.wst.jsdt.internal.ui.text.correction.SimilarElementsRequestor;

/**
*
* Provisional API: This class/interface is part of an interim API that is still under development and expected to
* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
* (repeatedly) as the API evolves.
*/
public class AddImportsOperation implements IWorkspaceRunnable {
	
	public static interface IChooseImportQuery {
		/**
		 * Selects an import from a list of choices.
		 * @param openChoices Array of found types
		 * @param containerName Name type to be imported
		 * @return Returns <code>null</code> to cancel the operation, or the
		 *         selected imports.
		 */
		TypeNameMatch chooseImport(TypeNameMatch[] openChoices, String containerName);
	}
	
	private IJavaScriptUnit fCompilationUnit;
	private final int fSelectionOffset;
	private final int fSelectionLength;
	private final IChooseImportQuery fQuery;
	private IStatus fStatus;
	private boolean fDoSave;
	
	
	/**
	 * Generate import statements for the passed java elements
	 * Elements must be of type IType (-> single import) or IPackageFragment
	 * (on-demand-import). Other JavaElements are ignored
	 * @param cu The compilation unit
	 * @param selectionOffset Start of the current text selection
	 * 	@param selectionLength End of the current text selection
	 * @param query Query element to be used for UI interaction or <code>null</code> to not select anything
	 * when multiple possibilities are available
	 * @param save If set, the result will be saved
	 */
	public AddImportsOperation(IJavaScriptUnit cu, int selectionOffset, int selectionLength, IChooseImportQuery query, boolean save) {
		super();
		Assert.isNotNull(cu);
		
		fCompilationUnit= cu;
		fSelectionOffset= selectionOffset;
		fSelectionLength= selectionLength;
		fQuery= query;
		fStatus= Status.OK_STATUS;
		fDoSave= save;
	}
	
	/**
	 * @return Returns the status.
	 */
	public IStatus getStatus() {
		return fStatus;
	}

	/**
	 * Runs the operation.
	 * @param monitor The progress monitor
	 * @throws CoreException  
	 * @throws OperationCanceledException Runtime error thrown when operation is canceled.
	 */
	public void run(IProgressMonitor monitor) throws CoreException, OperationCanceledException {
		if (monitor == null) {
			monitor= new NullProgressMonitor();
		}
		try {
			monitor.beginTask(CodeGenerationMessages.AddImportsOperation_description, 4); 
			
			JavaScriptUnit astRoot= JavaScriptPlugin.getDefault().getASTProvider().getAST(fCompilationUnit, ASTProvider.WAIT_YES, new SubProgressMonitor(monitor, 1));

			ImportRewrite importRewrite= StubUtility.createImportRewrite(astRoot, true);
			
			MultiTextEdit res= new MultiTextEdit();
			
			TextEdit edit= evaluateEdits(astRoot, importRewrite, fSelectionOffset, fSelectionLength, new SubProgressMonitor(monitor, 1));
			if (edit == null) {
				return;
			}
			res.addChild(edit);
				
			TextEdit importsEdit= importRewrite.rewriteImports(new SubProgressMonitor(monitor, 1));
			res.addChild(importsEdit);
			
			JavaModelUtil.applyEdit(fCompilationUnit, res, fDoSave, new SubProgressMonitor(monitor, 1));
		} catch (BadLocationException e) {
			throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e));
		} finally {
			monitor.done();
		}
	}
	
	private TextEdit evaluateEdits(JavaScriptUnit root, ImportRewrite importRewrite, int offset, int length, IProgressMonitor monitor) throws BadLocationException, JavaScriptModelException {
		SimpleName nameNode= null;
		if (root != null) { // got an AST
			ASTNode node= NodeFinder.perform(root, offset, length);

			if (node instanceof QualifiedName) {
				nameNode= ((QualifiedName) node).getName();
			} else if (node instanceof SimpleName) {
				nameNode= (SimpleName) node;
			}
		}
		
		String name, simpleName, containerName;
		int qualifierStart;
		int simpleNameStart;
		if (nameNode != null) {
			simpleName= nameNode.getIdentifier();
			simpleNameStart= nameNode.getStartPosition();
			if (nameNode.getLocationInParent() == QualifiedName.NAME_PROPERTY) {
				Name qualifier= ((QualifiedName) nameNode.getParent()).getQualifier();
				containerName= qualifier.getFullyQualifiedName();
				name= JavaModelUtil.concatenateName(containerName, simpleName);
				qualifierStart= qualifier.getStartPosition();
			} else if (nameNode.getParent().getLocationInParent() == QualifiedType.NAME_PROPERTY) {
				Type qualifier= ((QualifiedType) nameNode.getParent().getParent()).getQualifier();
				containerName= ASTNodes.asString(qualifier);
				name= JavaModelUtil.concatenateName(containerName, simpleName);
				qualifierStart= qualifier.getStartPosition();
			} else if (nameNode.getLocationInParent() == FunctionInvocation.NAME_PROPERTY) {
				ASTNode qualifier= ((FunctionInvocation) nameNode.getParent()).getExpression();
				if (qualifier instanceof Name) {
					containerName= ASTNodes.asString(qualifier);
					name= JavaModelUtil.concatenateName(containerName, simpleName);
					qualifierStart= qualifier.getStartPosition();
				} else {
					return null;
				}
			} else {
				containerName= ""; //$NON-NLS-1$
				name= simpleName;
				qualifierStart= simpleNameStart;
			}
			
			IBinding binding= nameNode.resolveBinding();
			if (binding != null && !binding.isRecovered()) {
				if (binding instanceof ITypeBinding) {
					ITypeBinding typeBinding= (ITypeBinding) binding;
					String qualifiedBindingName= typeBinding.getQualifiedName();
					if (containerName.length() > 0 && !qualifiedBindingName.equals(name)) {
						return null;
					}
					
					String res= importRewrite.addImport(typeBinding);
					if (containerName.length() > 0 && !res.equals(simpleName)) {
						// adding import failed
						return null;
					}
					return new ReplaceEdit(qualifierStart, simpleNameStart - qualifierStart, new String());
				} else if (binding instanceof IVariableBinding || binding instanceof IFunctionBinding) {
					boolean isField= binding instanceof IVariableBinding;
					ITypeBinding declaringClass= isField ? ((IVariableBinding) binding).getDeclaringClass() : ((IFunctionBinding) binding).getDeclaringClass();
					if (declaringClass == null) {
						return null; // variableBinding.getDeclaringClass() is null for array.length
					}
					if (Modifier.isStatic(binding.getModifiers())) {
						if (Modifier.isPrivate(declaringClass.getModifiers())) {
							fStatus= JavaUIStatus.createError(IStatus.ERROR, Messages.format(CodeGenerationMessages.AddImportsOperation_error_not_visible_class, declaringClass.getName()), null);
							return null;
						}
						
						if (containerName.length() > 0) { 
							if (containerName.equals(declaringClass.getName()) || containerName.equals(declaringClass.getQualifiedName()) ) {
								String res= importRewrite.addStaticImport(declaringClass.getQualifiedName(), binding.getName(), isField);
								if (!res.equals(simpleName)) {
									// adding import failed
									return null;
								}
								return new ReplaceEdit(qualifierStart, simpleNameStart - qualifierStart, ""); //$NON-NLS-1$
							}
						}
					}
					return null; // no static imports for packages
				} else {
					return null;
				}
			}
			if (binding != null && binding.getKind() != IBinding.TYPE) {
				// recovered binding
				return null; 
			}
			
		} else {
			IBuffer buffer= fCompilationUnit.getBuffer();
			
			qualifierStart= getNameStart(buffer, offset);
			int nameEnd= getNameEnd(buffer, offset + length);
			int len= nameEnd - qualifierStart;
			name= buffer.getText(qualifierStart, len).trim();
			if (name.length() == 0) {
				return null;
			}
			
			simpleName= Signature.getSimpleName(name);
			containerName= Signature.getQualifier(name);
			
			simpleNameStart= getSimpleNameStart(buffer, qualifierStart, containerName);
			
			int res= importRewrite.getDefaultImportRewriteContext().findInContext(containerName, simpleName, ImportRewriteContext.KIND_TYPE);
			if (res == ImportRewriteContext.RES_NAME_CONFLICT) {
				fStatus= JavaUIStatus.createError(IStatus.ERROR, CodeGenerationMessages.AddImportsOperation_error_importclash, null); 
				return null;
			} else if (res == ImportRewriteContext.RES_NAME_FOUND) {
				return new ReplaceEdit(qualifierStart, simpleNameStart - qualifierStart, ""); //$NON-NLS-1$
			}
		}
		IJavaScriptSearchScope searchScope= SearchEngine.createJavaSearchScope(new IJavaScriptElement[] { fCompilationUnit.getJavaScriptProject() });
		
		TypeNameMatch[] types= findAllTypes(simpleName, searchScope, nameNode, new SubProgressMonitor(monitor, 1));
		if (types.length == 0) {
			fStatus= JavaUIStatus.createError(IStatus.ERROR, Messages.format(CodeGenerationMessages.AddImportsOperation_error_notresolved_message, simpleName), null); 
			return null;
		}
		
		if (monitor.isCanceled()) {
			throw new OperationCanceledException();
		}
		TypeNameMatch chosen;
		if (types.length > 1 && fQuery != null) {
			chosen= fQuery.chooseImport(types, containerName);
			if (chosen == null) {
				throw new OperationCanceledException();
			}
		} else {
			chosen= types[0];
		}
		importRewrite.addImport(chosen.getFullyQualifiedName());
		return new ReplaceEdit(qualifierStart, simpleNameStart - qualifierStart, ""); //$NON-NLS-1$
	}

	
	private int getNameStart(IBuffer buffer, int pos) throws BadLocationException {
		while (pos > 0) {
			char ch= buffer.getChar(pos - 1);
			if (!Character.isJavaIdentifierPart(ch) && ch != '.') {
				return pos;
			}
			pos--;
		}
		return pos;
	}
	
	private int getNameEnd(IBuffer doc, int pos) throws BadLocationException {
		if (pos > 0) {
			if (Character.isWhitespace(doc.getChar(pos - 1))) {
				return pos;
			}
		}
		int len= doc.getLength();
		while (pos < len) {
			char ch= doc.getChar(pos);
			if (!Character.isJavaIdentifierPart(ch)) {
				return pos;
			}
			pos++;
		}
		return pos;
	}
	
	private int getSimpleNameStart(IBuffer buffer, int nameStart, String containerName) throws BadLocationException {
		int containerLen= containerName.length();
		int docLen= buffer.getLength();
		if ((containerLen > 0) && (nameStart + containerLen + 1 < docLen)) {
			for (int k= 0; k < containerLen; k++) {
				if (buffer.getChar(nameStart + k) != containerName.charAt(k)) {
					return nameStart;
				}
			}
			if (buffer.getChar(nameStart + containerLen) == '.') {
				return nameStart + containerLen + 1;
			}
		}
		return nameStart;
	}
	
	private int getSearchForConstant(int typeKinds) {
		final int CLASSES= SimilarElementsRequestor.CLASSES;
		final int INTERFACES= SimilarElementsRequestor.INTERFACES;
		final int ENUMS= SimilarElementsRequestor.ENUMS;
		final int ANNOTATIONS= SimilarElementsRequestor.ANNOTATIONS;

		switch (typeKinds & (CLASSES | INTERFACES | ENUMS | ANNOTATIONS)) {
			case CLASSES: return IJavaScriptSearchConstants.CLASS;
			case INTERFACES: return IJavaScriptSearchConstants.INTERFACE;
			case ENUMS: return IJavaScriptSearchConstants.ENUM;
			case ANNOTATIONS: return IJavaScriptSearchConstants.ANNOTATION_TYPE;
			case CLASSES | INTERFACES: return IJavaScriptSearchConstants.CLASS_AND_INTERFACE;
			case CLASSES | ENUMS: return IJavaScriptSearchConstants.CLASS_AND_ENUM;
			default: return IJavaScriptSearchConstants.TYPE;
		}
	}
	
	
	/*
	 * Finds a type by the simple name.
	 */
	private TypeNameMatch[] findAllTypes(String simpleTypeName, IJavaScriptSearchScope searchScope, SimpleName nameNode, IProgressMonitor monitor) throws JavaScriptModelException {
		boolean is50OrHigher= JavaModelUtil.is50OrHigher(fCompilationUnit.getJavaScriptProject());
		
		int typeKinds= SimilarElementsRequestor.ALL_TYPES;
		if (nameNode != null) {
			typeKinds= ASTResolving.getPossibleTypeKinds(nameNode, is50OrHigher);
		}
		
		ArrayList typeInfos= new ArrayList();
		TypeNameMatchCollector requestor= new TypeNameMatchCollector(typeInfos);
		int matchMode= SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE;
		new SearchEngine().searchAllTypeNames(null, matchMode, simpleTypeName.toCharArray(), matchMode, getSearchForConstant(typeKinds), searchScope, requestor, IJavaScriptSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, monitor);

		ArrayList typeRefsFound= new ArrayList(typeInfos.size());
		for (int i= 0, len= typeInfos.size(); i < len; i++) {
			TypeNameMatch curr= (TypeNameMatch) typeInfos.get(i);
			if (curr.getPackageName().length() > 0) { // do not suggest imports from the default package
				if (isOfKind(curr, typeKinds, is50OrHigher) && isVisible(curr)) {
					typeRefsFound.add(curr);
				}
			}
		}
		return (TypeNameMatch[]) typeRefsFound.toArray(new TypeNameMatch[typeRefsFound.size()]);
	}
	
	private boolean isOfKind(TypeNameMatch curr, int typeKinds, boolean is50OrHigher) {
		int flags= curr.getModifiers();
		if (Flags.isAnnotation(flags)) {
			return is50OrHigher && ((typeKinds & SimilarElementsRequestor.ANNOTATIONS) != 0);
		}
		if (Flags.isEnum(flags)) {
			return is50OrHigher && ((typeKinds & SimilarElementsRequestor.ENUMS) != 0);
		}
		if (Flags.isInterface(flags)) {
			return (typeKinds & SimilarElementsRequestor.INTERFACES) != 0;
		}
		return (typeKinds & SimilarElementsRequestor.CLASSES) != 0;
	}

	
	private boolean isVisible(TypeNameMatch curr) {
		int flags= curr.getModifiers();
		if (Flags.isPrivate(flags)) {
			return false;
		}
		if (Flags.isPublic(flags) || Flags.isProtected(flags)) {
			return true;
		}
		return curr.getPackageName().equals(fCompilationUnit.getParent().getElementName());
	}
	
	
	/**
	 * @return Returns the scheduling rule for this operation
	 */
	public ISchedulingRule getScheduleRule() {
		return fCompilationUnit.getJavaScriptProject().getResource();
	}
		
}
