package org.eclipse.jdt.internal.codeassist;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import java.util.Locale;

import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.env.*;

import org.eclipse.jdt.internal.codeassist.impl.*;
import org.eclipse.jdt.internal.codeassist.select.*;

import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.*;
import org.eclipse.jdt.internal.compiler.problem.*;
import org.eclipse.jdt.internal.compiler.util.*;
import org.eclipse.jdt.internal.compiler.impl.*;

/**
 * The selection engine is intended to infer the nature of a selected name in some
 * source code. This name can be qualified.
 *
 * Selection is resolving context using a name environment (no need to search), assuming
 * the source where selection occurred is correct and will not perform any completion
 * attempt. If this was the desired behavior, a call to the CompletionEngine should be
 * performed instead.
 */
public final class SelectionEngine extends Engine implements ISearchRequestor {
	SelectionParser parser;	
	ISearchableNameEnvironment nameEnvironment;
	ISelectionRequestor requestor;

	CompilationUnitScope unitScope;
	boolean acceptedAnswer;

	private int actualSelectionStart;
	private int actualSelectionEnd;
	private char[] qualifiedSelection;
	private char[] selectedIdentifier;
/**
 * The SelectionEngine is responsible for computing the selected object.
 *
 * It requires a searchable name environment, which supports some
 * specific search APIs, and a requestor to feed back the results to a UI.
 *
 *  @param environment com.ibm.codeassist.java.api.INameEnvironment
 *      used to resolve type/package references and search for types/packages
 *      based on partial names.
 *
 *  @param requestor com.ibm.codeassist.java.api.ISelectionRequestor
 *      since the engine might produce answers of various forms, the engine 
 *      is associated with a requestor able to accept all possible completions.
 *
 *  @param options com.ibm.compiler.java.api.ConfigurableOptions
 *		set of options used to configure the code assist engine.
 */

public SelectionEngine(ISearchableNameEnvironment nameEnvironment, ISelectionRequestor requestor, ConfigurableOption[] settings) {
	this.requestor = requestor;
	this.nameEnvironment = nameEnvironment;

	CompilerOptions options = new CompilerOptions(settings);
	ProblemReporter problemReporter =
		new ProblemReporter(
			DefaultErrorHandlingPolicies.proceedWithAllProblems(),
			options,
			new DefaultProblemFactory(Locale.getDefault())) {
				public void record(IProblem problem, CompilationResult unitResult) {
					unitResult.record(problem);
					SelectionEngine.this.requestor.acceptError(problem);
				}
			};

	this.parser = new SelectionParser(problemReporter);
	this.lookupEnvironment = new LookupEnvironment(this, options, problemReporter, nameEnvironment);
}
/**
 * One result of the search consists of a new class.
 *
 * NOTE - All package and type names are presented in their readable form:
 *    Package names are in the form "a.b.c".
 *    Nested type names are in the qualified form "A.M".
 *    The default package is represented by an empty array.
 */
public void acceptClass(char[] packageName, char[] className, int modifiers) {
	if (CharOperation.equals(className, selectedIdentifier)) {

		if (qualifiedSelection != null && !CharOperation.equals(qualifiedSelection, CharOperation.concat(packageName, className, '.'))){
			return;
		}
		
		requestor.acceptClass(
			packageName, 
			className, 
			mustQualifyType(CharOperation.splitOn('.', packageName), className));
		acceptedAnswer = true;
	}
}
/**
 * One result of the search consists of a new interface.
 *
 * NOTE - All package and type names are presented in their readable form:
 *    Package names are in the form "a.b.c".
 *    Nested type names are in the qualified form "A.I".
 *    The default package is represented by an empty array.
 */
public void acceptInterface(char[] packageName, char[] interfaceName, int modifiers) {
	if (CharOperation.equals(interfaceName, selectedIdentifier)) {

		if (qualifiedSelection != null && !CharOperation.equals(qualifiedSelection, CharOperation.concat(packageName, interfaceName, '.'))){
			return;
		}
		
		requestor.acceptInterface(
			packageName, 
			interfaceName,
			mustQualifyType(CharOperation.splitOn('.', packageName), interfaceName));
		acceptedAnswer = true;
	}
}
/**
 * One result of the search consists of a new package.
 *
 * NOTE - All package names are presented in their readable form:
 *    Package names are in the form "a.b.c".
 *    The default package is represented by an empty array.
 */
public void acceptPackage(char[] packageName) {
}
/**
 * One result of the search consists of a new type.
 *
 * NOTE - All package and type names are presented in their readable form:
 *    Package names are in the form "a.b.c".
 *    Nested type names are in the qualified form "A.M".
 *    The default package is represented by an empty array.
 */
public void acceptType(char[] packageName, char[] typeName) {
	acceptClass(packageName, typeName, 0);
}
private boolean checkSelection(char[] source, int selectionStart, int selectionEnd){
	
	Scanner scanner = new Scanner();
	scanner.setSourceBuffer(source);
	scanner.resetTo(selectionStart, selectionEnd);

	int lastIdentifierStart = -1;
	int lastIdentifierEnd = -1;
	int token, identCount = 0;
	char[] lastIdentifier = null;
	boolean expectingIdentifier = true;
	StringBuffer entireSelection = new StringBuffer(selectionEnd - selectionStart+1);
	do {
		try {
			token = scanner.getNextToken();
		} catch(InvalidInputException e) {
			return false;
		}
		switch(token){
			case TerminalSymbols.TokenNameIdentifier :
				if (!expectingIdentifier) return false;
				entireSelection.append(lastIdentifier = scanner.getCurrentIdentifierSource());
				lastIdentifierStart = scanner.startPosition;
				lastIdentifierEnd = scanner.currentPosition-1;
				identCount++;
				expectingIdentifier = false;
				break;
			case TerminalSymbols.TokenNameDOT :
				if (expectingIdentifier) return false;
				entireSelection.append('.');
				expectingIdentifier = true;
				break;
			case TerminalSymbols.TokenNameEOF :
				if (expectingIdentifier) return false;
				break;
			default:
				return false;
		}
	} while (token != TerminalSymbols.TokenNameEOF);
	if (lastIdentifierStart > 0){
		actualSelectionStart = lastIdentifierStart;
		actualSelectionEnd = lastIdentifierEnd;
		selectedIdentifier = lastIdentifier;
		if (identCount > 1) qualifiedSelection = entireSelection.toString().toCharArray();
		return true;
	}
	return false;
}
public AssistParser getParser(){
	return parser;
}
private boolean mustQualifyType(char[][] packageName, char[] readableTypeName) {
	// If there are no types defined into the current CU yet.
	if (unitScope == null)
		return true;
	if (CharOperation.equals(unitScope.fPackage.compoundName, packageName))
		return false;

	ImportBinding[] imports = unitScope.imports;
	for (int i = 0, length = imports.length; i < length; i++) {
		if (imports[i].onDemand) {
			if (CharOperation.equals(imports[i].compoundName, packageName))
				return false; // how do you match p1.p2.A.* ?
		} else if (CharOperation.equals(imports[i].readableName(), readableTypeName)) {
			return false;
		}
	}
	return true;
}
/**
 * Ask the engine to compute the selection at the specified position
 * of the given compilation unit.
 *
 *  @return void
 *      the selection result is answered through a requestor.
 *
 *  @param unit com.ibm.compiler.java.api.env.ICompilationUnit
 *      the source of the current compilation unit.
 *
 *  @param selectionSourceStart int
 *  @param selectionSourceEnd int
 *      a range in the source where the selection is.
 */
public void select(ICompilationUnit sourceUnit, int selectionSourceStart, int selectionSourceEnd) {

	char[] source = sourceUnit.getContents();
	if (!checkSelection(source, selectionSourceStart, selectionSourceEnd)) return;
	try{
		acceptedAnswer = false;
		CompilationResult result = new CompilationResult(sourceUnit, 1, 1);
		CompilationUnitDeclaration parsedUnit = parser.dietParse(sourceUnit, result, actualSelectionStart, actualSelectionEnd);

		if (parsedUnit != null) {
			// scan the package & import statements first
			if (parsedUnit.currentPackage instanceof SelectionOnPackageReference) {
				char[][] tokens = ((SelectionOnPackageReference) parsedUnit.currentPackage).tokens;
				requestor.acceptPackage(CharOperation.concatWith(tokens, '.'));
				return;
			}
			ImportReference[] imports = parsedUnit.imports;
			if (imports != null) {
				for (int i = 0, length = imports.length; i < length; i++) {
					ImportReference importReference = imports[i];
					if (importReference instanceof SelectionOnImportReference) {
						char[][] tokens = ((SelectionOnImportReference) importReference).tokens;
						requestor.acceptPackage(CharOperation.concatWith(tokens, '.'));
						nameEnvironment.findTypes(CharOperation.concatWith(tokens, '.'), this);
						if (!acceptedAnswer)
							nameEnvironment.findTypes(selectedIdentifier, this); // try with simple type name
						return;
					}
				}
			}

			if (parsedUnit.types != null) {
				lookupEnvironment.buildTypeBindings(parsedUnit);
				if (parsedUnit.scope != null) {
					try {
						lookupEnvironment.completeTypeBindings(parsedUnit, true);
						parsedUnit.scope.faultInTypes();
						parseMethod(parsedUnit, selectionSourceStart);
						parsedUnit.resolve();
					} catch (SelectionNodeFound e) {
						if (e.binding != null) { // if null then we found a problem in the selection node
							selectFrom(e.binding);
						}
					}
				}
			}
		}

		// only reaches here if no selection could be derived from the parsed tree
		// thus use the selected source and perform a textual type search
		if (!acceptedAnswer) {
			nameEnvironment.findTypes(selectedIdentifier, this);
		}
	} catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D		
	} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
	} finally {
		reset();
	}	
}
private void selectFrom(Binding binding) {
	if (binding instanceof ReferenceBinding) {
		ReferenceBinding typeBinding = (ReferenceBinding) binding;
		if (qualifiedSelection != null && !CharOperation.equals(qualifiedSelection, typeBinding.readableName())){
			return;
		}
		if (typeBinding.isInterface())
			requestor.acceptInterface(
				typeBinding.qualifiedPackageName(),
				typeBinding.qualifiedSourceName(),
				false); 
		else
			requestor.acceptClass(
				typeBinding.qualifiedPackageName(),
				typeBinding.qualifiedSourceName(),
				false);
		acceptedAnswer = true;
	} else if (binding instanceof MethodBinding) {
		MethodBinding methodBinding = (MethodBinding) binding;
		TypeBinding[] parameterTypes = methodBinding.parameters;
		int length = parameterTypes.length;
		char[][] parameterPackageNames = new char[length][];
		char[][] parameterTypeNames = new char[length][];
		for (int i = 0; i < length; i++) {
			parameterPackageNames[i] = parameterTypes[i].qualifiedPackageName();
			parameterTypeNames[i] = parameterTypes[i].qualifiedSourceName();
		}
		requestor.acceptMethod(
			methodBinding.declaringClass.qualifiedPackageName(),
			methodBinding.declaringClass.qualifiedSourceName(),
			methodBinding.isConstructor() ? methodBinding.declaringClass.sourceName() : methodBinding.selector,
			parameterPackageNames,
			parameterTypeNames);
		acceptedAnswer = true;
	} else if (binding instanceof FieldBinding) {
		FieldBinding fieldBinding = (FieldBinding) binding;
		if (fieldBinding.declaringClass != null){ // arraylength
			requestor.acceptField(
				fieldBinding.declaringClass.qualifiedPackageName(),
				fieldBinding.declaringClass.qualifiedSourceName(),
				fieldBinding.name);
			acceptedAnswer = true;
		}
	} else if (binding instanceof LocalVariableBinding) {
		selectFrom(((LocalVariableBinding) binding).type); // open on the type of the variable
	} else if (binding instanceof ArrayBinding) {
		selectFrom(((ArrayBinding) binding).leafComponentType); // open on the type of the array
	} else if (binding instanceof PackageBinding) {
		PackageBinding packageBinding = (PackageBinding) binding;
		requestor.acceptPackage(packageBinding.readableName());
		acceptedAnswer = true;
	}
}
/**
 * Asks the engine to compute the selection of the given type
 * from the source type.
 *
 *  @return void
 *      the selection result is answered through a requestor.
 *
 *  @param sourceType com.ibm.compiler.java.api.env.ISourceType
 *      a source form of the current type in which code assist is invoked.
 *
 *  @param typeName char[]
 *      a type name which is to be resolved in the context of a compilation unit.
 *		NOTE: the type name is supposed to be correctly reduced (no whitespaces, no unicodes left)
 */

public void selectType(ISourceType sourceType, char[] typeName) {
	try{
		acceptedAnswer = false;

		// find the outer most type
		ISourceType outerType = sourceType;
		ISourceType parent = sourceType.getEnclosingType();
		while (parent != null) {
			outerType = parent;
			parent = parent.getEnclosingType();
		}

		// compute parse tree for this most outer type
		CompilationResult result = new CompilationResult(outerType.getFileName(), 1, 1);
		CompilationUnitDeclaration parsedUnit = 
			SourceTypeConverter.buildCompilationUnit(
				outerType,
				false, // don't need field and methods
				this.parser.problemReporter(),
				result);

		if (parsedUnit != null && parsedUnit.types != null) {
			// find the type declaration that corresponds to the original source type
			char[] packageName = sourceType.getPackageName();
			char[] sourceTypeName = sourceType.getQualifiedName(); // the fully qualified name without the package name
			if (packageName != null) {
				// remove the package name if necessary
				sourceTypeName = CharOperation.subarray(sourceType.getQualifiedName(), packageName.length + 1, sourceTypeName.length);
			};
			TypeDeclaration typeDecl = parsedUnit.declarationOfType(CharOperation.splitOn('.', sourceTypeName));
			if (typeDecl != null) {
				
				// add fake field with the type we're looking for
				// note: since we didn't ask for fields above, there is no field defined yet
				FieldDeclaration field = new FieldDeclaration();
				int dot;
				if ((dot = CharOperation.lastIndexOf('.', typeName)) == -1) {
					this.selectedIdentifier = typeName;
					field.type = new SelectionOnSingleTypeReference(typeName, -1); // position not used
				} else {
					char[][] previousIdentifiers = CharOperation.splitOn('.', typeName, 0, dot - 1);
					char[] selectionIdentifier = CharOperation.subarray(typeName, dot + 1, typeName.length);
					this.selectedIdentifier = selectionIdentifier;
					field.type = 
						new SelectionOnQualifiedTypeReference(
							previousIdentifiers, 
							selectionIdentifier,
							new long[previousIdentifiers.length + 1]);
				}
				field.name = "<fakeField>"/*nonNLS*/.toCharArray();
				typeDecl.fields = new FieldDeclaration[] {field};

				// build bindings
				lookupEnvironment.buildTypeBindings(parsedUnit);
				if ((this.unitScope = parsedUnit.scope) != null) {
					try {
						// build fields
						// note: this builds fields only in the parsed unit (the buildFieldsAndMethods flag is not passed along)
						this.lookupEnvironment.completeTypeBindings(parsedUnit, true);

						// resolve
						parsedUnit.scope.faultInTypes();
						parsedUnit.resolve();
					} catch (SelectionNodeFound e) {
						if (e.binding != null) { // if null then we found a problem in the selection node
							selectFrom(e.binding);
						}
					}
				}
			}
		}
	
		// only reaches here if no selection could be derived from the parsed tree
		// thus use the selected source and perform a textual type search
		if (!acceptedAnswer) {
			if (this.selectedIdentifier != null) {
				nameEnvironment.findTypes(typeName, this);
			}
		}
	} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
	} finally {
		reset();
	}	
}
}
