/*******************************************************************************
 * Copyright (c) 2000, 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.compiler.lookup;

import java.util.HashMap;
import java.util.Map;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;

/**
 * Binding denoting a generic method after type parameter substitutions got performed.
 * On parameterized type bindings, all methods got substituted, regardless whether
 * their signature did involve generics or not, so as to get the proper declaringClass for
 * these methods.
 */
public class ParameterizedGenericMethodBinding extends ParameterizedMethodBinding implements Substitution {

    public TypeBinding[] typeArguments; 
    private LookupEnvironment environment;
    public boolean inferredReturnType;
    public boolean wasInferred; // only set to true for instances resulting from method invocation inferrence
    public boolean isRaw; // set to true for method behaving as raw for substitution purpose
    public MethodBinding tiebreakMethod;
	public boolean isUnchecked; // indicates whether inferred arguments used unchecked conversion during bound check or was raw
	
	/**
	 * Perform inference of generic method type parameters and/or expected type
	 */	
	public static MethodBinding computeCompatibleMethod(MethodBinding originalMethod, TypeBinding[] arguments, Scope scope, InvocationSite invocationSite) {
		
		ParameterizedGenericMethodBinding methodSubstitute;
		TypeVariableBinding[] typeVariables = originalMethod.typeVariables;
		TypeBinding[] substitutes = invocationSite.genericTypeArguments();
		
		computeSubstitutes: {
			if (substitutes != null) {
				// explicit type arguments got supplied
				if (substitutes.length != typeVariables.length) {
			        // incompatible due to wrong arity
			        return new ProblemMethodBinding(originalMethod, originalMethod.selector, substitutes, TypeParameterArityMismatch);
				}
				methodSubstitute = new ParameterizedGenericMethodBinding(originalMethod, substitutes, scope.environment());
				break computeSubstitutes;
			}
			
			// perform type argument inference (15.12.2.7)
				
			// initializes the map of substitutes (var --> type[][]{ equal, extends, super}
			TypeBinding[] parameters = originalMethod.parameters;
			int varLength = typeVariables.length;
			Map collectedSubstitutes = new HashMap(varLength);
			for (int i = 0; i < varLength; i++)
				collectedSubstitutes.put(typeVariables[i], new TypeBinding[3][]);
			
			substitutes = new TypeBinding[varLength];
			methodSubstitute = inferFromArgumentTypes(scope, originalMethod, arguments, parameters, collectedSubstitutes, substitutes);
			if (methodSubstitute == null) 
				return null;
			// substitutes may hold null to denote unresolved vars, but null arguments got replaced with respective original variable in param method
			
			// 15.12.2.8 - inferring unresolved type arguments
			if (hasUnresolvedTypeArgument(substitutes)) {
				TypeBinding expectedType = null;
				// if message invocation has expected type
				if (invocationSite instanceof MessageSend) {
					MessageSend message = (MessageSend) invocationSite;
					expectedType = message.expectedType;
				}
				TypeBinding upperBound = null;
				if (methodSubstitute.returnType.isTypeVariable()) {
					// should be: if no expected type, then assume Object
					// actually it rather seems to handle the returned variable case by expecting its erasure instead
					upperBound = methodSubstitute.returnType.erasure();
				} else {
					if (methodSubstitute.returnType.id != TypeIds.T_void)
						upperBound = scope.getJavaLangObject(); 
				}
				// Object o = foo(); // where <T extends Serializable> T foo();
				if (expectedType == null || upperBound.isCompatibleWith(expectedType)) {
					expectedType = upperBound;
				}
				methodSubstitute = methodSubstitute.inferFromExpectedType(scope, expectedType, collectedSubstitutes, substitutes);
				if (methodSubstitute == null) 
					return null;
			}
		}

		// bounds check
		if (!methodSubstitute.isRaw) {
			for (int i = 0, length = typeVariables.length; i < length; i++) {
			    TypeVariableBinding typeVariable = typeVariables[i];
			    TypeBinding substitute = methodSubstitute.typeArguments[i];
				switch (typeVariable.boundCheck(methodSubstitute, substitute)) {
					case TypeConstants.MISMATCH :
				        // incompatible due to bound check
				        return new ProblemMethodBinding(methodSubstitute, originalMethod.selector, new TypeBinding[]{substitute, typeVariables[i] }, ParameterBoundMismatch);
					case TypeConstants.UNCHECKED :
						// tolerate unchecked bounds
						methodSubstitute.isUnchecked = true;
						break;
				}
			}
		}

		return methodSubstitute;
	}

	/**
	 * Returns true if any unresolved variable is detected, i.e. any variable is substituted with itself
	 */
	private static boolean hasUnresolvedTypeArgument(TypeBinding[] substitutes) {
		for (int i = 0, varLength = substitutes.length; i <varLength; i++) {
			if (substitutes[i] == null) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Collect argument type mapping, handling varargs
	 */
	private static ParameterizedGenericMethodBinding inferFromArgumentTypes(Scope scope, MethodBinding originalMethod, TypeBinding[] arguments, TypeBinding[] parameters, Map collectedSubstitutes, TypeBinding[] substitutes) {

		if (originalMethod.isVarargs()) {
			int paramLength = parameters.length;
			int minArgLength = paramLength - 1;
			int argLength = arguments.length;
			// process mandatory arguments
			for (int i = 0; i < minArgLength; i++) {
				parameters[i].collectSubstitutes(scope, arguments[i], collectedSubstitutes, CONSTRAINT_EXTENDS);
			}
			// process optional arguments
			if (minArgLength < argLength) {
				TypeBinding varargType = parameters[minArgLength]; // last arg type - as is ?
				TypeBinding lastArgument = arguments[minArgLength];
				if (paramLength != argLength // argument is passed as is ?
						||  (lastArgument != NullBinding
								&& (lastArgument.dimensions() == 0 || lastArgument.leafComponentType().isBaseType() != varargType.leafComponentType().isBaseType()))) { 
					varargType = ((ArrayBinding)varargType).elementsType(); // eliminate one array dimension
				}
				for (int i = minArgLength; i < argLength; i++) {
					varargType.collectSubstitutes(scope, arguments[i], collectedSubstitutes, CONSTRAINT_EXTENDS);
				}
			}
		} else {
			int paramLength = parameters.length;
			for (int i = 0; i < paramLength; i++) {
				parameters[i].collectSubstitutes(scope, arguments[i], collectedSubstitutes, CONSTRAINT_EXTENDS);
			}
		}
		TypeVariableBinding[] originalVariables = originalMethod.typeVariables;
		int varLength = originalVariables.length;
		substitutes = resolveSubstituteConstraints(scope, originalVariables , substitutes, false/*ignore Ti<:Uk*/, collectedSubstitutes);
		if (substitutes == null) 
			return null; // incompatible
		if (substitutes.length == 0) {
			// raw generic method inferred
			return new ParameterizedGenericMethodBinding(originalMethod, (RawTypeBinding)null, scope.environment());
		}
		// apply inferred variable substitutions - replacing unresolved variable with original ones in param method
		TypeBinding[] resolvedSubstitutes = substitutes;
		for (int i = 0; i < varLength; i++) {
			if (substitutes[i] == null) {
				if (resolvedSubstitutes == substitutes) {
					System.arraycopy(substitutes, 0, resolvedSubstitutes = new TypeBinding[varLength], 0, i); // clone to replace null with original variable in param method
				}
				resolvedSubstitutes[i] = originalVariables[i];
			} else if (resolvedSubstitutes != substitutes) {
				resolvedSubstitutes[i] = substitutes[i];
			}
		}
		return new ParameterizedGenericMethodBinding(originalMethod, resolvedSubstitutes, scope.environment());		
	}
	
	private static TypeBinding[] resolveSubstituteConstraints(Scope scope, TypeVariableBinding[] typeVariables, TypeBinding[] substitutes, boolean considerEXTENDSConstraints, Map collectedSubstitutes) {
		if (collectedSubstitutes.isEmpty()) {
			// raw generic method inferred
			return NoTypes; // empty array
		}
		int varLength = typeVariables.length;
		
		// check Tj=U constraints
		nextTypeParameter: 
			for (int i = 0; i < varLength; i++) {
				TypeVariableBinding current = typeVariables[i];
				TypeBinding substitute = substitutes[i];
				if (substitute != null) continue nextTypeParameter; // already inferred previously
				TypeBinding[][] variableSubstitutes = (TypeBinding[][]) collectedSubstitutes.get(current);
				TypeBinding [] equalSubstitutes = variableSubstitutes[CONSTRAINT_EQUAL];
				if (equalSubstitutes != null) {
					nextConstraint:
						for (int j = 0, equalLength = equalSubstitutes.length; j < equalLength; j++) {
							TypeBinding equalSubstitute = equalSubstitutes[j];
							if (equalSubstitute == null) continue nextConstraint;
//							if (equalSubstitute == current) continue nextConstraint;
//							if (equalSubstitute.isTypeVariable()) {
//								TypeVariableBinding variable = (TypeVariableBinding) equalSubstitute;
//								// substituted by a variable of the same method, ignore
//								if (variable.rank < varLength && typeVariables[variable.rank] == variable) {
//									// TODO (philippe) rewrite all other constraints to use current instead.
//									continue nextConstraint;
//								}
//							}
							substitutes[i] = equalSubstitute;
							continue nextTypeParameter; // pick first match, applicability check will rule out invalid scenario where others were present
						}
				}
			}
		if (hasUnresolvedTypeArgument(substitutes)) {
			// check Tj>:U constraints
			nextTypeParameter: 
				for (int i = 0; i < varLength; i++) {
					TypeVariableBinding current = typeVariables[i];
					TypeBinding substitute = substitutes[i];
					if (substitute != null) continue nextTypeParameter; // already inferred previously
					TypeBinding[][] variableSubstitutes = (TypeBinding[][]) collectedSubstitutes.get(current);
					TypeBinding [] bounds = variableSubstitutes[CONSTRAINT_SUPER];
					if (bounds == null) continue nextTypeParameter;
					TypeBinding mostSpecificSubstitute = scope.lowerUpperBound(bounds);
					if (mostSpecificSubstitute == null)
						return null; // incompatible
					if (mostSpecificSubstitute != VoidBinding) {
						substitutes[i] = mostSpecificSubstitute;
					}
				}
		}
		if (considerEXTENDSConstraints && hasUnresolvedTypeArgument(substitutes)) {
			// check Tj<:U constraints
			nextTypeParameter: 
				for (int i = 0; i < varLength; i++) {
					TypeVariableBinding current = typeVariables[i];
					TypeBinding substitute = substitutes[i];
					if (substitute != null) continue nextTypeParameter; // already inferred previously
					TypeBinding[][] variableSubstitutes = (TypeBinding[][]) collectedSubstitutes.get(current);
					TypeBinding [] bounds = variableSubstitutes[CONSTRAINT_EXTENDS];
					if (bounds == null) continue nextTypeParameter;
					TypeBinding[] glb = Scope.greaterLowerBound(bounds);
					TypeBinding mostSpecificSubstitute = null;
					if (glb != null) mostSpecificSubstitute = glb[0]; // TODO (philippe) need to improve
						//TypeBinding mostSpecificSubstitute = scope.greaterLowerBound(bounds);
						if (mostSpecificSubstitute != null) {
							substitutes[i] = mostSpecificSubstitute;
						}
					} 
		}
		return substitutes;
	}
	
	/**
	 * Create raw generic method for raw type (double substitution from type vars with raw type arguments, and erasure of method variables)
	 * Only invoked for non-static generic methods of raw type
	 */
	public ParameterizedGenericMethodBinding(MethodBinding originalMethod, RawTypeBinding rawType, LookupEnvironment environment) {

		TypeVariableBinding[] originalVariables = originalMethod.typeVariables;
		int length = originalVariables.length;
		TypeBinding[] rawArguments = new TypeBinding[length];
		for (int i = 0; i < length; i++) {
			rawArguments[i] = originalVariables[i].erasure();
		}		
	    this.isRaw = true;
		this.isUnchecked = false;
	    this.environment = environment;
		this.modifiers = originalMethod.modifiers;
		this.selector = originalMethod.selector;
		this.declaringClass = rawType == null ? originalMethod.declaringClass : rawType;
	    this.typeVariables = NoTypeVariables;
	    this.typeArguments = rawArguments;
	    this.originalMethod = originalMethod;
		boolean ignoreRawTypeSubstitution = rawType == null || originalMethod.isStatic();
	    this.parameters = Scope.substitute(this, ignoreRawTypeSubstitution
	    									? originalMethod.parameters // no substitution if original was static
	    									: Scope.substitute(rawType, originalMethod.parameters));
	    this.thrownExceptions = Scope.substitute(this, 	ignoreRawTypeSubstitution 
	    									? originalMethod.thrownExceptions // no substitution if original was static
	    									: Scope.substitute(rawType, originalMethod.thrownExceptions));
	    this.returnType = Scope.substitute(this, ignoreRawTypeSubstitution 
	    									? originalMethod.returnType // no substitution if original was static
	    									: Scope.substitute(rawType, originalMethod.returnType));
	    this.wasInferred = false; // not resulting from method invocation inferrence
	}
    
    /**
     * Create method of parameterized type, substituting original parameters with type arguments.
     */
	public ParameterizedGenericMethodBinding(MethodBinding originalMethod, TypeBinding[] typeArguments, LookupEnvironment environment) {

	    this.environment = environment;
		this.modifiers = originalMethod.modifiers;
		this.selector = originalMethod.selector;
		this.declaringClass = originalMethod.declaringClass;
	    this.typeVariables = NoTypeVariables;
	    this.typeArguments = typeArguments;
	    this.isRaw = false;
		this.isUnchecked = false;
	    this.originalMethod = originalMethod;
	    this.parameters = Scope.substitute(this, originalMethod.parameters);
	    this.thrownExceptions = Scope.substitute(this, originalMethod.thrownExceptions);
	    this.returnType = Scope.substitute(this, originalMethod.returnType);
	    this.wasInferred = true;// resulting from method invocation inferrence
	}

	/*
	 * parameterizedDeclaringUniqueKey dot selector originalMethodGenericSignature percent typeArguments
	 * p.X<U> { <T> void bar(T t, U u) { new X<String>().bar(this, "") } } --> Lp/X<Ljava/lang/String;>;.bar<T:Ljava/lang/Object;>(TT;TU;)V^123%<Lp/X;>
	 */
	public char[] computeUniqueKey(boolean withAccessFlags) {
		if (this.isRaw)
			return super.computeUniqueKey(withAccessFlags);
		StringBuffer buffer = new StringBuffer();
		buffer.append(super.computeUniqueKey(withAccessFlags));
		buffer.append('%');
		buffer.append('<');
		int length = this.typeArguments.length;
		for (int i = 0; i < length; i++) {
			TypeBinding typeArgument = this.typeArguments[i];
			buffer.append(typeArgument.computeUniqueKey(false/*without access flags*/));
		}
		buffer.append('>');
		int resultLength = buffer.length();
		char[] result = new char[resultLength];
		buffer.getChars(0, resultLength, result, 0);	
		return result;
		
	}
	
	/**
	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#environment()
	 */
	public LookupEnvironment environment() {
		return this.environment;
	}
	/**
	 * Returns true if some parameters got substituted.
	 * NOTE: generic method invocation delegates to its declaring method (could be a parameterized one)
	 */
	public boolean hasSubstitutedParameters() {
		// generic parameterized method can represent either an invocation or a raw generic method
		if (this.wasInferred) 
			return this.originalMethod.hasSubstitutedParameters();
		return super.hasSubstitutedParameters();
	}
	/**
	 * Returns true if the return type got substituted.
	 * NOTE: generic method invocation delegates to its declaring method (could be a parameterized one)
	 */
	public boolean hasSubstitutedReturnType() {
		if (this.inferredReturnType) 
			return this.originalMethod.hasSubstitutedReturnType();
		return super.hasSubstitutedReturnType();
	}
	/**
	 * Given some type expectation, and type variable bounds, perform some inference.
	 * Returns true if still had unresolved type variable at the end of the operation
	 */
	private ParameterizedGenericMethodBinding inferFromExpectedType(Scope scope, TypeBinding expectedType, Map collectedSubstitutes, TypeBinding[] substitutes) {
	    TypeVariableBinding[] originalVariables = this.originalMethod.typeVariables; // immediate parent (could be a parameterized method)
		int varLength = originalVariables.length;
		
		computeSubstitutes: {
		    // infer from expected return type
			if (expectedType != null) {
			    returnType.collectSubstitutes(scope, expectedType, collectedSubstitutes, CONSTRAINT_SUPER);
			}
		    // infer from bounds of type parameters
			for (int i = 0; i < varLength; i++) {
				TypeVariableBinding originalVariable = originalVariables[i];
				TypeBinding argument = this.typeArguments[i];
				if (originalVariable.firstBound == originalVariable.superclass) {
					Scope.substitute(this, originalVariable.firstBound) // substitue original bound with resolved variables
						.collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS);
				}
				for (int j = 0, max = originalVariable.superInterfaces.length; j < max; j++) {
					Scope.substitute(this, originalVariable.superInterfaces[j]) // substitue original bound with resolved variables
						.collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS);
				}
			}
			substitutes = resolveSubstituteConstraints(scope, originalVariables, substitutes, true/*consider Ti<:Uk*/, collectedSubstitutes);
			if (substitutes == null) 
				return null; // incompatible
			if (substitutes.length == 0) {
		    	// raw generic method inferred
		    	this.isRaw = true;
				this.isUnchecked = false;
		    	for (int i = 0; i < varLength; i++) {
		    		this.typeArguments[i] = originalVariables[i].erasure();
		    	}
		    	break computeSubstitutes;
			}
			// this.typeArguments = substitutes; - no op since side effects got performed during #resolveSubstituteConstraints
	    	for (int i = 0; i < varLength; i++) {
	    		TypeBinding substitute = substitutes[i];
	    		if (substitute != null) {
	    			this.typeArguments[i] = substitutes[i];
	    		} else {
	    			// remaining unresolved variable are considered to be Object (or their bound actually)
		    		this.typeArguments[i] = originalVariables[i].erasure();
		    	}
	    	}
		}		
		// adjust method types to reflect latest inference
		TypeBinding oldReturnType = this.returnType;
		this.returnType = Scope.substitute(this, this.returnType);
		this.inferredReturnType = this.returnType != oldReturnType;
	    this.parameters = Scope.substitute(this, this.parameters);
	    this.thrownExceptions = Scope.substitute(this, this.thrownExceptions);
	    return this;
	}

	/**
	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#isRawSubstitution()
	 */
	public boolean isRawSubstitution() {
		return this.isRaw;
	}
	
	/**
	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#substitute(org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding)
	 */
	public TypeBinding substitute(TypeVariableBinding originalVariable) {
        TypeVariableBinding[] variables = this.originalMethod.typeVariables;
        int length = variables.length;
        // check this variable can be substituted given parameterized type
        if (originalVariable.rank < length && variables[originalVariable.rank] == originalVariable) {
			return this.typeArguments[originalVariable.rank];
        }
        if (!this.isStatic() && this.declaringClass instanceof Substitution) {
        	return ((Substitution)this.declaringClass).substitute(originalVariable);
        }
	    return originalVariable;
	}
	/**
	 * Returns the method to use during tiebreak (usually the method itself).
	 * For generic method invocations, tiebreak needs to use generic method with erasure substitutes.
	 */
	public MethodBinding tiebreakMethod() {
		if (this.tiebreakMethod == null) {
			this.tiebreakMethod = new ParameterizedGenericMethodBinding(this.originalMethod, (RawTypeBinding)null, this.environment);
		} 
		return this.tiebreakMethod;
	}	
}
