/*******************************************************************************
 * 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.jdt.internal.corext.refactoring.structure;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.Assert;

import org.eclipse.jdt.core.IField;
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.ui.JavaPlugin;

/**
 * Utilities to create mappings between type variables of different types in a type hierarchy.
 */
public final class TypeVariableUtil {

	/**
	 * Returns the composition of two type variable mappings. The type variables signatures can have an arbitrary format.
	 *
	 * @param first
	 *        the first type variable mapping
	 * @param second
	 *        the second type variable mapping
	 * @return the possibly empty composed type variable mapping
	 */
	public static TypeVariableMaplet[] composeMappings(final TypeVariableMaplet[] first, final TypeVariableMaplet[] second) {
		Assert.isNotNull(first);
		Assert.isNotNull(second);

		if (first.length == 0)
			return first;
		else if (second.length == 0)
			return second;
		else {
			TypeVariableMaplet source= null;
			TypeVariableMaplet target= null;
			final Set<TypeVariableMaplet> set= new HashSet<TypeVariableMaplet>(first.length * second.length);
			for (int index= 0; index < first.length; index++) {
				for (int offset= 0; offset < second.length; offset++) {
					source= first[index];
					target= second[offset];
					if (source.getTargetIndex() == target.getSourceIndex() && source.getTargetName().equals(target.getSourceName()))
						set.add(new TypeVariableMaplet(source.getSourceName(), index, target.getTargetName(), offset));
				}
			}
			final TypeVariableMaplet[] mapping= new TypeVariableMaplet[set.size()];
			set.toArray(mapping);
			return mapping;
		}
	}

	/**
	 * Extracts the type variables from a signature
	 *
	 * @param signature
	 *        the signature to extract the type variables from
	 * @param variables
	 *        the set of variables to fill in
	 */
	private static void extractTypeVariables(final String signature, final Set<String> variables) {
		Assert.isNotNull(signature);
		Assert.isNotNull(variables);

		final String[] arguments= Signature.getTypeArguments(signature);
		if (arguments.length == 0) {
			variables.add(Signature.toString(signature));
		} else {
			for (int index= 0; index < arguments.length; index++)
				variables.add(Signature.toString(arguments[index]));
		}
	}

	/**
	 * Returns the type variables referenced in the signature of the specified member.
	 *
	 * @param declaring
	 *        The declaring type of the specified member
	 * @param member
	 *        the member to get its type variables. Can be a type, field or a method.
	 * @return a possibly empty array of type variable candidates
	 * @throws JavaModelException
	 *         if the signature of the specified member could not be resolved
	 */
	private static String[] getReferencedVariables(final IType declaring, final IMember member) throws JavaModelException {

		Assert.isNotNull(declaring);
		Assert.isNotNull(member);

		final String[] variables= parametersToVariables(declaring.getTypeParameters());
		String[] result= new String[0];
		if (member instanceof IField) {
			final String signature= ((IField) member).getTypeSignature();
			final String[] signatures= getVariableSignatures(signature);
			if (signatures.length == 0) {
				final String variable= Signature.toString(signature);
				for (int index= 0; index < variables.length; index++) {
					if (variable.equals(variables[index])) {
						result= new String[] { variable};
						break;
					}
				}
			} else {
				result= new String[signatures.length];
				for (int index= 0; index < result.length; index++)
					result[index]= Signature.toString(signatures[index]);
			}
		} else if (member instanceof IMethod) {
			final IMethod method= (IMethod) member;
			final HashSet<String> set= new HashSet<String>();
			final String[] types= method.getParameterTypes();
			for (int index= 0; index < types.length; index++)
				extractTypeVariables(types[index], set);
			extractTypeVariables(method.getReturnType(), set);
			final String[] arguments= parametersToVariables(((IMethod) member).getTypeParameters());
			for (int index= 0; index < arguments.length; index++)
				set.add(arguments[index]);
			result= new String[set.size()];
			set.toArray(result);
		} else if (member instanceof IType)
			result= parametersToVariables(((IType) member).getTypeParameters());
		else {
			JavaPlugin.logErrorMessage("Unexpected sub-type of IMember: " + member.getClass().getName()); //$NON-NLS-1$
			Assert.isTrue(false);
		}

		final List<String> list= new ArrayList<String>(variables.length);
		String variable= null;
		for (int index= 0; index < variables.length; index++) {
			variable= variables[index];
			for (int offset= 0; offset < result.length; offset++)
				if (variable.equals(result[offset]))
					list.add(result[offset]);
		}
		result= new String[list.size()];
		list.toArray(result);
		return result;
	}

	/**
	 * Returns all type variable names of the indicated member not mapped by the specified type variable mapping.
	 *
	 * @param mapping
	 *        the type variable mapping. The entries of this mapping must be simple type variable names.
	 * @param declaring
	 *        the declaring type of the indicated member
	 * @param member
	 *        the member to determine its unmapped type variable names
	 * @return a possibly empty array of unmapped type variable names
	 * @throws JavaModelException
	 *         if the type parameters of the member could not be determined
	 */
	public static String[] getUnmappedVariables(final TypeVariableMaplet[] mapping, final IType declaring, final IMember member) throws JavaModelException {

		Assert.isNotNull(mapping);
		Assert.isNotNull(declaring);
		Assert.isNotNull(member);

		List<String> list= null;
		final String[] types= getReferencedVariables(declaring, member);
		if (mapping.length == 0) {
			list= new ArrayList<String>(types.length);
			list.addAll(Arrays.asList(types));
		} else {
			final Set<String> mapped= new HashSet<String>(types.length);
			String type= null;
			for (int index= 0; index < types.length; index++) {
				for (int offset= 0; offset < mapping.length; offset++) {
					type= types[index];
					if (mapping[offset].getSourceName().equals(type))
						mapped.add(type);
				}
			}
			list= new ArrayList<String>(types.length - mapped.size());
			for (int index= 0; index < types.length; index++) {
				type= types[index];
				if (!mapped.contains(type))
					list.add(type);
			}
		}
		final String[] result= new String[list.size()];
		list.toArray(result);
		return result;
	}

	/**
	 * Returns the type variable signatures of the specified parameterized type signature, or an empty array if none.
	 *
	 * @param signature
	 *        the signature to get its type variable signatures from. The signature must be a parameterized type signature.
	 * @return a possibly empty array of type variable signatures
	 * @see Signature#getTypeArguments(String)
	 */
	private static String[] getVariableSignatures(final String signature) {
		Assert.isNotNull(signature);

		String[] result= null;
		try {
			result= Signature.getTypeArguments(signature);
		} catch (IllegalArgumentException exception) {
			result= new String[0];
		}
		return result;
	}

	/**
	 * Returns the reversed type variable mapping of the specified mapping.
	 *
	 * @param mapping
	 *        the mapping to inverse
	 * @return the possibly empty inverse mapping
	 */
	public static TypeVariableMaplet[] inverseMapping(final TypeVariableMaplet[] mapping) {
		Assert.isNotNull(mapping);

		final TypeVariableMaplet[] result= new TypeVariableMaplet[mapping.length];
		TypeVariableMaplet maplet= null;
		for (int index= 0; index < mapping.length; index++) {
			maplet= mapping[index];
			result[index]= new TypeVariableMaplet(maplet.getTargetName(), maplet.getTargetIndex(), maplet.getSourceName(), maplet.getSourceIndex());
		}
		return result;
	}

	/**
	 * Creates a type variable mapping from a domain to a range.
	 *
	 * @param domain
	 *        the domain of the mapping
	 * @param range
	 *        the range of the mapping
	 * @param indexes
	 *        <code>true</code> if the indexes should be compared, <code>false</code> if the names should be compared
	 * @return a possibly empty type variable mapping
	 */
	private static TypeVariableMaplet[] parametersToSignatures(final ITypeParameter[] domain, final String[] range, final boolean indexes) {
		Assert.isNotNull(domain);
		Assert.isNotNull(range);

		final Set<TypeVariableMaplet> set= new HashSet<TypeVariableMaplet>();
		ITypeParameter source= null;
		String target= null;
		String element= null;
		String signature= null;
		for (int index= 0; index < domain.length; index++) {
			source= domain[index];
			for (int offset= 0; offset < range.length; offset++) {
				target= range[offset];
				element= source.getElementName();
				signature= Signature.toString(target);
				if (indexes) {
					if (offset == index)
						set.add(new TypeVariableMaplet(element, index, signature, offset));
				} else {
					if (element.equals(signature))
						set.add(new TypeVariableMaplet(element, index, signature, offset));
				}
			}
		}
		final TypeVariableMaplet[] result= new TypeVariableMaplet[set.size()];
		set.toArray(result);
		return result;
	}

	/**
	 * Converts the specified type parameters to type variable names.
	 *
	 * @param parameters
	 *        the type parameters to convert.
	 * @return the converted type variable names
	 * @see ITypeParameter#getElementName()
	 */
	private static String[] parametersToVariables(final ITypeParameter[] parameters) {
		Assert.isNotNull(parameters);

		String[] result= new String[parameters.length];
		for (int index= 0; index < parameters.length; index++)
			result[index]= parameters[index].getElementName();

		return result;
	}

	/**
	 * Creates a type variable mapping from a domain to a range.
	 *
	 * @param domain
	 *        the domain of the mapping
	 * @param range
	 *        the range of the mapping
	 * @return a possibly empty type variable mapping
	 */
	private static TypeVariableMaplet[] signaturesToParameters(final String[] domain, final ITypeParameter[] range) {
		Assert.isNotNull(domain);
		Assert.isNotNull(range);
		Assert.isTrue(domain.length == 0 || domain.length == range.length);

		final List<TypeVariableMaplet> list= new ArrayList<TypeVariableMaplet>();
		String source= null;
		String target= null;
		for (int index= 0; index < domain.length; index++) {
			source= Signature.toString(domain[index]);
			target= range[index].getElementName();
			list.add(new TypeVariableMaplet(source, index, target, index));
		}
		final TypeVariableMaplet[] result= new TypeVariableMaplet[list.size()];
		list.toArray(result);
		return result;
	}

	/**
	 * Returns a type variable mapping from a subclass to a superclass.
	 *
	 * @param type
	 *        the type representing the subclass class
	 * @return a type variable mapping. The mapping entries consist of simple type variable names.
	 * @throws JavaModelException
	 *         if the signature of one of the types involved could not be retrieved
	 */
	public static TypeVariableMaplet[] subTypeToInheritedType(final IType type) throws JavaModelException {
		Assert.isNotNull(type);

		final ITypeParameter[] domain= type.getTypeParameters();
		if (domain.length > 0) {
			final String signature= type.getSuperclassTypeSignature();
			if (signature != null) {
				final String[] range= getVariableSignatures(signature);
				if (range.length > 0)
					return parametersToSignatures(domain, range, false);
			}
		}
		return new TypeVariableMaplet[0];
	}

	/**
	 * Returns a type variable mapping from a subclass to a superclass.
	 *
	 * @param subtype
	 *        the type representing the subclass
	 * @param supertype
	 *        the type representing the superclass
	 * @return a type variable mapping. The mapping entries consist of simple type variable names.
	 * @throws JavaModelException
	 *         if the signature of one of the types involved could not be retrieved
	 */
	public static TypeVariableMaplet[] subTypeToSuperType(final IType subtype, final IType supertype) throws JavaModelException {
		Assert.isNotNull(subtype);
		Assert.isNotNull(supertype);

		final TypeVariableMaplet[] mapping= subTypeToInheritedType(subtype);
		if (mapping.length > 0) {
			final ITypeParameter[] range= supertype.getTypeParameters();
			if (range.length > 0) {
				final String signature= subtype.getSuperclassTypeSignature();
				if (signature != null) {
					final String[] domain= getVariableSignatures(signature);
					if (domain.length > 0)
						return composeMappings(mapping, signaturesToParameters(domain, range));
				}
			}
		}
		return mapping;
	}

	/**
	 * Returns a type variable mapping from a superclass to a subclass.
	 *
	 * @param supertype
	 *        the type representing the superclass
	 * @param subtype
	 *        the type representing the subclass
	 * @return a type variable mapping. The mapping entries consist of simple type variable names.
	 * @throws JavaModelException
	 *         if the signature of one of the types involved could not be retrieved
	 */
	public static TypeVariableMaplet[] superTypeToInheritedType(final IType supertype, final IType subtype) throws JavaModelException {
		Assert.isNotNull(subtype);
		Assert.isNotNull(supertype);

		final ITypeParameter[] domain= supertype.getTypeParameters();
		if (domain.length > 0) {
			final String signature= subtype.getSuperclassTypeSignature();
			if (signature != null) {
				final String[] range= getVariableSignatures(signature);
				if (range.length > 0)
					return parametersToSignatures(domain, range, true);
			}
		}
		return new TypeVariableMaplet[0];
	}

	/**
	 * Returns a type variable mapping from a superclass to a subclass.
	 *
	 * @param supertype
	 *        the type representing the superclass
	 * @param subtype
	 *        the type representing the subclass
	 * @return a type variable mapping. The mapping entries consist of simple type variable names.
	 * @throws JavaModelException
	 *         if the signature of one of the types involved could not be retrieved
	 */
	public static TypeVariableMaplet[] superTypeToSubType(final IType supertype, final IType subtype) throws JavaModelException {
		Assert.isNotNull(supertype);
		Assert.isNotNull(subtype);

		return inverseMapping(subTypeToSuperType(subtype, supertype));
	}

	private TypeVariableUtil() {
		// Not to be instantiated
	}
}
