/*******************************************************************************
 * Copyright (c) 2005 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.jdt.internal.core.util;

import java.util.ArrayList;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypes;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;

public class BindingKeyResolver extends BindingKeyParser {
	Compiler compiler;
	Binding compilerBinding;
	
	char[][] compoundName;
	int dimension;
	LookupEnvironment environment;
	ReferenceBinding genericType;
	MethodBinding methodBinding;
	
	CompilationUnitDeclaration parsedUnit;
	BlockScope scope;
	TypeBinding typeBinding;
	TypeDeclaration typeDeclaration;
	ArrayList types = new ArrayList();
	
	boolean isCapture;
	int wildcardKind = -1;
	
	private BindingKeyResolver(BindingKeyParser parser, Compiler compiler, LookupEnvironment environment) {
		super(parser);
		this.compiler = compiler;
		this.environment = environment;
	}
	
	public BindingKeyResolver(String key) {
		this(key, null, null);
	}

	public BindingKeyResolver(String key, Compiler compiler, LookupEnvironment environment) {
		super(key);
		this.compiler = compiler;
		this.environment = environment;
	}
	
	/*
	 * If not already cached, computes and cache the compound name (pkg name + top level name) of this key.
	 * Returns the package name if key is a pkg key.
	 * Returns an empty array if malformed.
	 * This key's scanner should be positioned on the package or type token.
	 */
	public char[][] compoundName() {
		return this.compoundName;
	}
	 
	public void consumeArrayDimension(char[] brakets) {
		this.dimension = brakets.length;
	}
	
	public void consumeCapture() {
		this.isCapture = true;
	}
	
	public void consumeField(char[] fieldName) {
		FieldBinding[] fields = ((ReferenceBinding) this.typeBinding).fields();
	 	for (int i = 0, length = fields.length; i < length; i++) {
			FieldBinding field = fields[i];
			if (CharOperation.equals(fieldName, field.name)) {
				this.compilerBinding = field;
				return;
			}
		}
	}

	public void consumeParameterizedMethod() {
		TypeBinding[] arguments = getTypeBindingArguments();
		if (arguments.length != this.methodBinding.typeVariables().length) return;
	 	this.methodBinding = new ParameterizedGenericMethodBinding(this.methodBinding, arguments, this.environment);
		this.compilerBinding = this.methodBinding;
	}
	
	public void consumeLocalType(char[] uniqueKey) {
 		LocalTypeBinding[] localTypeBindings  = this.parsedUnit.localTypes;
 		for (int i = 0; i < this.parsedUnit.localTypeCount; i++)
 			if (CharOperation.equals(uniqueKey, localTypeBindings[i].computeUniqueKey(false/*without access flags*/))) {
 				this.typeBinding = localTypeBindings[i];
				this.compilerBinding = this.typeBinding;
 				return;
 			}
	}

	public void consumeLocalVar(char[] varName) {
		if (this.scope == null) {
			this.scope = this.methodBinding.sourceMethod().scope;
		}
	 	for (int i = 0; i < this.scope.localIndex; i++) {
			LocalVariableBinding local = this.scope.locals[i];
			if (CharOperation.equals(varName, local.name)) {
				this.compilerBinding = local;
				return;
			}
		}
	}

	public void consumeMethod(char[] selector, char[] signature) {
		MethodBinding[] methods = ((ReferenceBinding) this.typeBinding).methods();
	 	for (int i = 0, methodLength = methods.length; i < methodLength; i++) {
			MethodBinding method = methods[i];
			if (CharOperation.equals(selector, method.selector) || (selector.length == 0 && method.isConstructor())) {
				char[] methodSignature = method.original().genericSignature();
				if (methodSignature == null)
					methodSignature = method.signature();
				if (CharOperation.equals(signature, methodSignature)) {
					this.methodBinding = method;
					this.compilerBinding = this.methodBinding;
					return;
				}
			}
		}
	}
	
	public void consumeMemberType(char[] simpleTypeName) {
		this.typeBinding = getTypeBinding(simpleTypeName);
		this.compilerBinding = this.typeBinding;
	}

	public void consumePackage(char[] pkgName) {
		this.compoundName = CharOperation.splitOn('/', pkgName);
		this.compilerBinding = new PackageBinding(this.compoundName, null, this.environment);
	}
	
	public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
		TypeBinding[] arguments = getTypeBindingArguments();
		if (simpleTypeName != null) {
			// parameterized member type
			this.genericType = this.genericType.getMemberType(simpleTypeName);
			if (!isRaw)
				this.typeBinding = this.environment.createParameterizedType(this.genericType, arguments, (ReferenceBinding) this.typeBinding);
			else
				// raw type
				this.typeBinding = this.environment.createRawType(this.genericType, (ReferenceBinding) this.typeBinding);
		} else {
			// parameterized top level type
			this.genericType = (ReferenceBinding) this.typeBinding;
			this.typeBinding = this.environment.createParameterizedType(this.genericType, arguments, null);
		}
		this.compilerBinding = this.typeBinding;
	}
	

	public void consumeParser(BindingKeyParser parser) {
		this.types.add(parser);
	}
	
	public void consumeScope(int scopeNumber) {
		if (this.scope == null) {
			this.scope = this.methodBinding.sourceMethod().scope;
		}
		if (scopeNumber >= this.scope.subscopeCount)
			return; // malformed key
		this.scope = (BlockScope) this.scope.subscopes[scopeNumber];
	}
	
	public void consumeRawType() {
		if (this.typeBinding == null) return;
		this.typeBinding = this.environment.createRawType((ReferenceBinding) this.typeBinding, null/*no enclosing type*/);
	}
	public void consumeSecondaryType(char[] simpleTypeName) {
		if (this.parsedUnit == null) return;
		this.typeDeclaration = null; // start from the parsed unit
		this.typeBinding = getTypeBinding(simpleTypeName);
		this.compilerBinding = this.typeBinding;
	}
	
	public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
		this.compoundName = CharOperation.splitOn('/', fullyQualifiedName);
	}
	
	public void consumeTopLevelType() {
		if (this.compoundName.length == 1 && this.compoundName[0].length == 1) {
			// case of base type
 			TypeBinding baseTypeBinding = getBaseTypeBinding(this.compoundName[0]);
 			if (baseTypeBinding != null) {
				this.typeBinding = baseTypeBinding;
				this.compilerBinding = this.typeBinding;
				return;
 			}
		}
		this.parsedUnit = getCompilationUnitDeclaration();
		if (this.parsedUnit != null && this.compiler != null) {
			this.compiler.process(this.parsedUnit, this.compiler.totalUnits+1); // noop if unit has already been resolved
		}
		if (this.parsedUnit == null) {
			this.typeBinding = getBinaryBinding();
			this.compilerBinding = this.typeBinding;
		} else {
			char[] typeName = this.compoundName[this.compoundName.length-1];
			this.typeBinding = getTypeBinding(typeName);
			this.compilerBinding = this.typeBinding;
		}
	}
	
	public void consumeType() {
		this.typeBinding = getArrayBinding(this.dimension, this.typeBinding);
		this.compilerBinding = this.typeBinding;
	}
	
	public void consumeTypeVariable(char[] typeVariableName) {
	 	TypeVariableBinding[] typeVariableBindings = this.methodBinding != null ? this.methodBinding.typeVariables() : this.typeBinding.typeVariables();
	 	for (int i = 0, length = typeVariableBindings.length; i < length; i++) {
			TypeVariableBinding typeVariableBinding = typeVariableBindings[i];
			if (CharOperation.equals(typeVariableName, typeVariableBinding.sourceName())) {
				this.compilerBinding = typeVariableBinding;
				return;
			}
		}
	}
	
	public void consumeWildCard(int kind) {
		this.wildcardKind = kind;
	}
	
	/*
	 * If the given dimension is greater than 0 returns an array binding for the given type binding.
	 * Otherwise return the given type binding.
	 * Returns null if the given type binding is null.
	 */
	private TypeBinding getArrayBinding(int dim, TypeBinding binding) {
		if (binding == null) return null;
		if (dim == 0) return binding;
		return this.environment.createArrayType(binding, dim);
	}
	
	private TypeBinding getBaseTypeBinding(char[] signature) {
		switch (signature[0]) {
			case 'I' :
				return BaseTypes.IntBinding;
			case 'Z' :
				return BaseTypes.BooleanBinding;
			case 'V' :
				return BaseTypes.VoidBinding;
			case 'C' :
				return BaseTypes.CharBinding;
			case 'D' :
				return BaseTypes.DoubleBinding;
			case 'B' :
				return BaseTypes.ByteBinding;
			case 'F' :
				return BaseTypes.FloatBinding;
			case 'J' :
				return BaseTypes.LongBinding;
			case 'S' :
				return BaseTypes.ShortBinding;
			case 'N':
				return BaseTypes.NullBinding;
			default :
				return null;
		}
	}
	 
	/*
	 * Returns a binary binding corresonding to this key's compound name.
	 * Returns null if not found.
	 */
	private TypeBinding getBinaryBinding() {
		return this.environment.getType(this.compoundName);
	}
	 
	/*
	 * Finds the compilation unit declaration corresponding to the key in the given lookup environment.
	 * Returns null if no compilation unit declaration could be found.
	 * This key's scanner should be positioned on the package token.
	 */
	public CompilationUnitDeclaration getCompilationUnitDeclaration() {
		char[][] name = compoundName();
		if (name.length == 0) return null;
		if (this.environment == null) return null;
		ReferenceBinding binding = this.environment.getType(name);
		if (!(binding instanceof SourceTypeBinding)) return null;
		SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) binding;
		if (sourceTypeBinding.scope == null) 
			return null;
		return sourceTypeBinding.scope.compilationUnitScope().referenceContext;
	}
	 
	/*
	 * Returns the compiler binding corresponding to this key.
	 * Returns null is malformed.
	 * This key's scanner should be positioned on the package token.
	 */
	public Binding getCompilerBinding() {
		parse();
		return this.compilerBinding;
	}
	
	private TypeBinding getTypeBinding(char[] simpleTypeName) {
		if (this.typeBinding instanceof BinaryTypeBinding) {
			return ((BinaryTypeBinding) this.typeBinding).getMemberType(simpleTypeName);
		} else {
			TypeDeclaration[] typeDeclarations = 
				this.typeDeclaration == null ? 
					(this.parsedUnit == null ? null : this.parsedUnit.types) : 
					this.typeDeclaration.memberTypes;
			if (typeDeclarations == null) return null;
			for (int i = 0, length = typeDeclarations.length; i < length; i++) {
				TypeDeclaration declaration = typeDeclarations[i];
				if (CharOperation.equals(simpleTypeName, declaration.name)) {
					this.typeDeclaration = declaration;
					return declaration.binding;
				}
			}
		}
		return null;
	}
	
	private TypeBinding[] getTypeBindingArguments() {
		int size = this.types.size();
		TypeBinding[] arguments = new TypeBinding[size];
		int rank = 0;
		for (int i = 0; i < size; i++) {
			BindingKeyResolver resolver = (BindingKeyResolver) this.types.get(i);
			TypeBinding binding;
			int kind = resolver.wildcardKind;
			switch (kind) {
				case Wildcard.EXTENDS:
				case Wildcard.SUPER:
					binding = this.environment.createWildcard((ReferenceBinding) this.typeBinding, rank++, (TypeBinding) resolver.compilerBinding, null /*no extra bound*/, kind);
					break;
				case Wildcard.UNBOUND:
					binding = this.environment.createWildcard((ReferenceBinding) this.typeBinding, rank++, null/*no bound*/, null /*no extra bound*/, kind);
					break;
				default:
					binding = (TypeBinding) resolver.compilerBinding;
			}
			if (resolver.isCapture)
				binding = new CaptureBinding((WildcardBinding) binding);
			arguments[i] = binding;
		}
		this.types = new ArrayList();
		return arguments;
	}
	 
	public void malformedKey() {
		this.compoundName = CharOperation.NO_CHAR_CHAR;
	}
	
	public BindingKeyParser newParser() {
		return new BindingKeyResolver(this, this.compiler, this.environment);
	}
	 
	public String toString() {
		return getKey();
	}

}
