/*******************************************************************************
 * Copyright (c) 2000, 2011 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.ui.text.java;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;

import org.eclipse.jdt.internal.corext.template.java.SignatureUtil;


/**
 * Proposal info that computes the javadoc lazily when it is queried.
 *
 * @since 3.1
 */
public final class MethodProposalInfo extends MemberProposalInfo {

	/**
	 * Fallback in case we can't match a generic method. The fall back is only based
	 * on method name and number of parameters.
	 */
	private IMethod fFallbackMatch;

	/**
	 * Creates a new proposal info.
	 *
	 * @param project the java project to reference when resolving types
	 * @param proposal the proposal to generate information for
	 */
	public MethodProposalInfo(IJavaProject project, CompletionProposal proposal) {
		super(project, proposal);
	}

	/**
	 * Resolves the member described by the receiver and returns it if found.
	 * Returns <code>null</code> if no corresponding member can be found.
	 *
	 * @return the resolved member or <code>null</code> if none is found
	 * @throws JavaModelException if accessing the java model fails
	 */
	@Override
	protected IMember resolveMember() throws JavaModelException {
		char[] declarationSignature= fProposal.getDeclarationSignature();
		String typeName= SignatureUtil.stripSignatureToFQN(String.valueOf(declarationSignature));
		IType type= fJavaProject.findType(typeName);
		if (type != null) {
			String name= String.valueOf(fProposal.getName());
			String[] parameters= Signature.getParameterTypes(String.valueOf(SignatureUtil.fix83600(fProposal.getSignature())));
			for (int i= 0; i < parameters.length; i++) {
				parameters[i]= SignatureUtil.getLowerBound(parameters[i]);
			}
			boolean isConstructor= fProposal.isConstructor();

			return findMethod(name, parameters, isConstructor, type);
		}

		return null;
	}

	/* adapted from JavaModelUtil */

	/**
	 * Finds a method in a type. This searches for a method with the same name and signature.
	 * Parameter types are only compared by the simple name, no resolving for the fully qualified
	 * type name is done. Constructors are only compared by parameters, not the name.
	 * 
	 * @param name The name of the method to find
	 * @param paramTypes The type signatures of the parameters e.g. <code>{"QString;","I"}</code>
	 * @param isConstructor If the method is a constructor
	 * @param type the type
	 * @return The first found method or <code>null</code>, if nothing found
	 * @throws JavaModelException if accessing the Java model fails
	 */
	private IMethod findMethod(String name, String[] paramTypes, boolean isConstructor, IType type) throws JavaModelException {
		Map<String, char[]> typeVariables= computeTypeVariables(type);
		return findMethod(name, paramTypes, isConstructor, type, typeVariables);
	}

	/**
	 * The type and method signatures received in
	 * <code>CompletionProposals</code> of type <code>METHOD_REF</code>
	 * contain concrete type bounds. When comparing parameters of the signature
	 * with an <code>IMethod</code>, we have to make sure that we match the
	 * case where the formal method declaration uses a type variable which in
	 * the signature is already substituted with a concrete type (bound).
	 * <p>
	 * This method creates a map from type variable names to type signatures
	 * based on the position they appear in the type declaration. The type
	 * signatures are filtered through
	 * {@link SignatureUtil#getLowerBound(char[])}.
	 * </p>
	 *
	 * @param type the type to get the variables from
	 * @return a map from type variables to concrete type signatures
	 * @throws JavaModelException if accessing the java model fails
	 */
	private Map<String, char[]> computeTypeVariables(IType type) throws JavaModelException {
		Map<String, char[]> map= new HashMap<>();
		char[] declarationSignature= fProposal.getDeclarationSignature();
		if (declarationSignature == null) // array methods don't contain a declaration signature
			return map;
		char[][] concreteParameters= Signature.getTypeArguments(declarationSignature);

		ITypeParameter[] typeParameters= type.getTypeParameters();
		for (int i= 0; i < typeParameters.length; i++) {
			String variable= typeParameters[i].getElementName();
			if (concreteParameters.length > i)
				// use lower bound since method equality is only parameter based
				map.put(variable, SignatureUtil.getLowerBound(concreteParameters[i]));
			else
				// fProposal.getDeclarationSignature() is a raw type - use Object
				map.put(variable, "Ljava.lang.Object;".toCharArray()); //$NON-NLS-1$
		}

		return map;
	}

	/**
	 * Finds a method by name. This searches for a method with a name and
	 * signature. Parameter types are only compared by the simple name, no
	 * resolving for the fully qualified type name is done. Constructors are
	 * only compared by parameters, not the name.
	 *
	 * @param name The name of the method to find
	 * @param paramTypes The type signatures of the parameters e.g.
	 *        <code>{"QString;","I"}</code>
	 * @param isConstructor If the method is a constructor
	 * @param type the given type in which to search for methods
	 * @param typeVariables a map from type variables to concretely used types
	 * @return The found method or <code>null</code>, if nothing found
	 * @throws JavaModelException if the method does not exist or if an exception occurs while accessing its corresponding resource
	 */
	private IMethod findMethod(String name, String[] paramTypes, boolean isConstructor, IType type, Map<String, char[]> typeVariables) throws JavaModelException {
		IMethod[] methods = type.getMethods();
		for (int i= methods.length - 1; i >= 0; i--) {
			if (isSameMethodSignature(name, paramTypes, isConstructor, methods[i], typeVariables, type)) {
				return methods[i];
			}
		}
		return fFallbackMatch;
	}

	/**
	 * Tests if a method equals to the given signature. Parameter types are only
	 * compared by the simple name, no resolving for the fully qualified type
	 * name is done. Constructors are only compared by parameters, not the name.
	 *
	 * @param name Name of the method
	 * @param paramTypes The type signatures of the parameters e.g.
	 *        <code>{"QString;","I"}</code>
	 * @param isConstructor Specifies if the method is a constructor
	 * @param method the method to be compared with this info's method
	 * @param typeVariables a map from type variables to types
	 * @param type the given type that declares the method
	 * @return Returns <code>true</code> if the method has the given name and
	 *         parameter types and constructor state.
	 * @throws JavaModelException if the method does not exist or if an exception occurs while accessing its corresponding resource
	 */
	private boolean isSameMethodSignature(String name, String[] paramTypes, boolean isConstructor, IMethod method, Map<String, char[]> typeVariables, IType type) throws JavaModelException {
		if (isConstructor || name.equals(method.getElementName())) {
			if (isConstructor == method.isConstructor()) {
				String[] otherParams= method.getParameterTypes(); // types may be type variables
				boolean isBinaryConstructorForNonStaticMemberClass=
						method.isBinary()
						&& type.isMember()
						&& !Flags.isStatic(type.getFlags());
				int syntheticParameterCorrection= isBinaryConstructorForNonStaticMemberClass && paramTypes.length == otherParams.length - 1 ? 1 : 0;
				if (paramTypes.length == otherParams.length - syntheticParameterCorrection) {
					fFallbackMatch= method;
					String signature= method.getSignature();
					String[] otherParamsFromSignature= Signature.getParameterTypes(signature); // types are resolved / upper-bounded
					// no need to check method type variables since these are
					// not yet bound when proposing a method
					for (int i= 0; i < paramTypes.length; i++) {
						String ourParamName= computeSimpleTypeName(paramTypes[i], typeVariables);
						String otherParamName1= computeSimpleTypeName(otherParams[i + syntheticParameterCorrection], typeVariables);
						String otherParamName2= computeSimpleTypeName(otherParamsFromSignature[i + syntheticParameterCorrection], typeVariables);
	
						if (!ourParamName.equals(otherParamName1) && !ourParamName.equals(otherParamName2)) {
							return false;
						}
					}
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Returns the simple erased name for a given type signature, possibly replacing type variables.
	 *
	 * @param signature the type signature
	 * @param typeVariables the Map&lt;SimpleName, VariableName>
	 * @return the simple erased name for signature
	 */
	private String computeSimpleTypeName(String signature, Map<String, char[]> typeVariables) {
		// method equality uses erased types
		String erasure= Signature.getTypeErasure(signature);
		erasure= erasure.replaceAll("/", ".");  //$NON-NLS-1$//$NON-NLS-2$
		String simpleName= Signature.getSimpleName(Signature.toString(erasure));
		char[] typeVar= typeVariables.get(simpleName);
		if (typeVar != null)
			simpleName= String.valueOf(Signature.getSignatureSimpleName(typeVar));
		return simpleName;
	}
}
