/*******************************************************************************
 * 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.corext.refactoring.generics;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;

import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ArrayType;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.HierarchyType;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.EnumeratedTypeSet;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.SingletonTypeSet;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSetEnvironment;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ArrayElementVariable2;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ArrayTypeVariable2;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.CastVariable2;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.CollectionElementVariable2;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ConstraintVariable2;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeConstraint2;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.IndependentTypeVariable2;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TTypes;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TypeEquivalenceSet;


public class InferTypeArgumentsConstraintsSolver {

	private static class TTypeComparator implements Comparator<TType> {
		public int compare(TType o1, TType o2) {
			return o1.getPrettySignature().compareTo(o2.getPrettySignature());
		}
		public static TTypeComparator INSTANCE= new TTypeComparator();
	}

	private final static String CHOSEN_TYPE= "chosenType"; //$NON-NLS-1$

	private final InferTypeArgumentsTCModel fTCModel;
	private TypeSetEnvironment fTypeSetEnvironment;

	/**
	 * The work-list used by the type constraint solver to hold the set of
	 * nodes in the constraint graph that remain to be (re-)processed. Entries
	 * are <code>ConstraintVariable2</code>s.
	 */
	private LinkedList<ConstraintVariable2> fWorkList;

	private InferTypeArgumentsUpdate fUpdate;


	public InferTypeArgumentsConstraintsSolver(InferTypeArgumentsTCModel typeConstraintFactory) {
		fTCModel= typeConstraintFactory;
		fWorkList= new LinkedList<ConstraintVariable2>();
	}

	public InferTypeArgumentsUpdate solveConstraints(IProgressMonitor pm) {
		pm.beginTask("", 2); //$NON-NLS-1$
		fUpdate= new InferTypeArgumentsUpdate();

		ConstraintVariable2[] allConstraintVariables= fTCModel.getAllConstraintVariables();
		if (allConstraintVariables.length == 0)
			return fUpdate;

		fTypeSetEnvironment= new TypeSetEnvironment(fTCModel.getTypeEnvironment());
		ParametricStructureComputer parametricStructureComputer= new ParametricStructureComputer(allConstraintVariables, fTCModel);
		Collection<CollectionElementVariable2> newVars= parametricStructureComputer.createElemConstraintVariables();

		ArrayList<ConstraintVariable2> newAllConstraintVariables= new ArrayList<ConstraintVariable2>();
		newAllConstraintVariables.addAll(Arrays.asList(allConstraintVariables));
		newAllConstraintVariables.addAll(newVars);
		allConstraintVariables= newAllConstraintVariables.toArray(new ConstraintVariable2[newAllConstraintVariables.size()]);


		//loop over all TypeEquivalenceSets and unify the elements from the fElemStructureEnv with the existing TypeEquivalenceSets
		HashSet<TypeEquivalenceSet> allTypeEquivalenceSets= new HashSet<TypeEquivalenceSet>();
		for (int i= 0; i < allConstraintVariables.length; i++) {
			TypeEquivalenceSet typeEquivalenceSet= allConstraintVariables[i].getTypeEquivalenceSet();
			if (typeEquivalenceSet != null)
				allTypeEquivalenceSets.add(typeEquivalenceSet);
		}
		for (Iterator<TypeEquivalenceSet> iter= allTypeEquivalenceSets.iterator(); iter.hasNext();) {
			TypeEquivalenceSet typeEquivalenceSet= iter.next();
			ConstraintVariable2[] contributingVariables= typeEquivalenceSet.getContributingVariables();
			for (int i= 0; i < contributingVariables.length; i++) {
				for (int j= i + 1; j < contributingVariables.length; j++) {
					ConstraintVariable2 first= contributingVariables[i];
					ConstraintVariable2 second= contributingVariables[j];
					fTCModel.createElementEqualsConstraints(first, second); // recursively
				}
			}
		}
		ITypeConstraint2[] allTypeConstraints= fTCModel.getAllTypeConstraints();
		for (int i= 0; i < allTypeConstraints.length; i++) {
			ITypeConstraint2 typeConstraint= allTypeConstraints[i];
			fTCModel.createElementEqualsConstraints(typeConstraint.getLeft(), typeConstraint.getRight());
		}

		initializeTypeEstimates(allConstraintVariables);
		if (pm.isCanceled())
			throw new OperationCanceledException();
		fWorkList.addAll(Arrays.asList(allConstraintVariables));
		runSolver(new SubProgressMonitor(pm, 1));
		chooseTypes(allConstraintVariables, new SubProgressMonitor(pm, 1));
		findCastsToRemove(fTCModel.getCastVariables());
		return fUpdate;
	}

	private void initializeTypeEstimates(ConstraintVariable2[] allConstraintVariables) {
		for (int i= 0; i < allConstraintVariables.length; i++) {
			ConstraintVariable2 cv= allConstraintVariables[i];
			//TODO: not necessary for types that are not used in a TypeConstraint but only as type in CollectionElementVariable
			//TODO: handle nested element variables; see ParametricStructureComputer.createAndInitVars()
			TypeEquivalenceSet set= cv.getTypeEquivalenceSet();
			if (set == null) {
				set= new TypeEquivalenceSet(cv);
				set.setTypeEstimate(createInitialEstimate(cv));
				cv.setTypeEquivalenceSet(set);
			} else {
				TypeSet typeEstimate= (TypeSet) cv.getTypeEstimate();
				if (typeEstimate == null) {
					ConstraintVariable2[] cvs= set.getContributingVariables();
					typeEstimate= fTypeSetEnvironment.getUniverseTypeSet();
					for (int j= 0; j < cvs.length; j++) //TODO: optimize: just try to find an immutable CV; if not found, use Universe
						typeEstimate= typeEstimate.intersectedWith(createInitialEstimate(cvs[j]));
					set.setTypeEstimate(typeEstimate);
				}
			}
		}
	}

	private TypeSet createInitialEstimate(ConstraintVariable2 cv) {
		// TODO: check assumption: only immutable CVs have a type
//		ParametricStructure parametricStructure= fElemStructureEnv.elemStructure(cv);
//		if (parametricStructure != null && parametricStructure != ParametricStructureComputer.ParametricStructure.NONE) {
//			return SubTypesOfSingleton.create(parametricStructure.getBase());
//		}

		TType type= cv.getType();
		if (type == null) {
			return fTypeSetEnvironment.getUniverseTypeSet();

		} else if (cv instanceof IndependentTypeVariable2) {
			return fTypeSetEnvironment.getUniverseTypeSet();
			//TODO: solve problem with recursive bounds
//			TypeVariable tv= (TypeVariable) type;
//			TType[] bounds= tv.getBounds();
//			TypeSet result= SubTypesOfSingleton.create(bounds[0].getErasure());
//			for (int i= 1; i < bounds.length; i++) {
//				result= result.intersectedWith(SubTypesOfSingleton.create(bounds[i].getErasure()));
//			}
//			return result;

		} else if (cv instanceof ArrayTypeVariable2) {
			return fTypeSetEnvironment.getUniverseTypeSet();
		} else if (cv instanceof ArrayElementVariable2) {
			if (cv.getType() != null && cv.getType().isTypeVariable()) {
				return fTypeSetEnvironment.getUniverseTypeSet();
			} else {
				return new SingletonTypeSet(type, fTypeSetEnvironment);
			}

		} else if (type.isVoidType()) {
			return fTypeSetEnvironment.getEmptyTypeSet();
		} else {
			return new SingletonTypeSet(type, fTypeSetEnvironment);
		}
	}

	private void runSolver(SubProgressMonitor pm) {
		pm.beginTask("", fWorkList.size() * 3); //$NON-NLS-1$
		while (! fWorkList.isEmpty()) {
			// Get a variable whose type estimate has changed
			ConstraintVariable2 cv= fWorkList.removeFirst();
			List<ITypeConstraint2> usedIn= fTCModel.getUsedIn(cv);
			processConstraints(usedIn);
			pm.worked(1);
			if (pm.isCanceled())
				throw new OperationCanceledException();
		}
		pm.done();
	}

	/**
	 * Given a list of <code>ITypeConstraint2</code>s that all refer to a
	 * given <code>ConstraintVariable2</code> (whose type bound has presumably
	 * just changed), process each <code>ITypeConstraint</code>, propagating
	 * the type bound across the constraint as needed.
	 *
	 * @param usedIn the <code>List</code> of <code>ITypeConstraint2</code>s
	 * to process
	 */
	private void processConstraints(List<ITypeConstraint2> usedIn) {
		Iterator<ITypeConstraint2> iter= usedIn.iterator();
		while (iter.hasNext()) {
			ITypeConstraint2 tc= iter.next();

				maintainSimpleConstraint(tc);
				//TODO: prune tcs which cannot cause further changes
				// Maybe these should be pruned after a special first loop over all ConstraintVariables,
				// Since this can only happen once for every CV in the work list.
//				if (isConstantConstraint(stc))
//					fTypeConstraintFactory.removeUsedIn(stc, changedCv);
		}
	}

	private void maintainSimpleConstraint(ITypeConstraint2 stc) {
		ConstraintVariable2 left= stc.getLeft();
		ConstraintVariable2 right= stc.getRight();

		TypeEquivalenceSet leftSet= left.getTypeEquivalenceSet();
		TypeEquivalenceSet rightSet= right.getTypeEquivalenceSet();
		TypeSet leftEstimate= (TypeSet) leftSet.getTypeEstimate();
		TypeSet rightEstimate= (TypeSet) rightSet.getTypeEstimate();

		if (leftEstimate.isUniverse() && rightEstimate.isUniverse())
			return; // nothing to do

		if (leftEstimate.equals(rightEstimate))
			return; // nothing to do

		TypeSet lhsSuperTypes= leftEstimate.superTypes();
		TypeSet rhsSubTypes= rightEstimate.subTypes();

		if (! rhsSubTypes.containsAll(leftEstimate)) {
			TypeSet xsection= leftEstimate.intersectedWith(rhsSubTypes);

//			if (xsection.isEmpty()) // too bad, but this can happen
//				throw new IllegalStateException("Type estimate set is now empty for LHS in " + left + " <= " + right + "; estimates were " + leftEstimate + " <= " + rightEstimate); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$

			leftSet.setTypeEstimate(xsection);
			fWorkList.addAll(Arrays.asList(leftSet.getContributingVariables()));
		}
		if (! lhsSuperTypes.containsAll(rightEstimate)) {
			TypeSet xsection= rightEstimate.intersectedWith(lhsSuperTypes);

//			if (xsection.isEmpty())
//				throw new IllegalStateException("Type estimate set is now empty for RHS in " + left + " <= " + right + "; estimates were " + leftEstimate + " <= " + rightEstimate); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$

			rightSet.setTypeEstimate(xsection);
			fWorkList.addAll(Arrays.asList(rightSet.getContributingVariables()));
		}
	}

	private void chooseTypes(ConstraintVariable2[] allConstraintVariables, SubProgressMonitor pm) {
		pm.beginTask("", allConstraintVariables.length); //$NON-NLS-1$
		for (int i= 0; i < allConstraintVariables.length; i++) {
			ConstraintVariable2 cv= allConstraintVariables[i];

			TypeEquivalenceSet set= cv.getTypeEquivalenceSet();
			if (set == null)
				continue; //TODO: should not happen iff all unused constraint variables got pruned
			//TODO: should calculate only once per EquivalenceRepresentative; can throw away estimate TypeSet afterwards
			TType type= chooseSingleType((TypeSet) cv.getTypeEstimate()); //TODO: is null for Universe TypeSet
			setChosenType(cv, type);

			if (cv instanceof CollectionElementVariable2) {
				CollectionElementVariable2 elementCv= (CollectionElementVariable2) cv;
				fUpdate.addDeclaration(elementCv);
			}

			pm.worked(1);
			if (pm.isCanceled())
				throw new OperationCanceledException();
		}
		pm.done();
	}

	private TType chooseSingleType(TypeSet typeEstimate) {
		if (typeEstimate.isUniverse() || typeEstimate.isEmpty()) {
			return null;

		} else if (typeEstimate.hasUniqueLowerBound()) {
			return typeEstimate.uniqueLowerBound();

		} else {
			EnumeratedTypeSet lowerBound= typeEstimate.lowerBound().enumerate();
			ArrayList<TType> interfaceCandidates= null;
			for (Iterator<TType> iter= lowerBound.iterator(); iter.hasNext();) {
				TType type= iter.next();
				if (! type.isInterface()) {
					return type;
				} else {
					if (interfaceCandidates == null)
						interfaceCandidates= new ArrayList<TType>(2);
					interfaceCandidates.add(type);
				}
			}

			if (interfaceCandidates == null || interfaceCandidates.size() == 0) {
				return null;
			} else if (interfaceCandidates.size() == 1) {
				return interfaceCandidates.get(0);
			} else {
				ArrayList<TType> nontaggingCandidates= getNonTaggingInterfaces(interfaceCandidates);
				if (nontaggingCandidates.size() != 0) {
					return Collections.min(nontaggingCandidates, TTypeComparator.INSTANCE);
				} else {
					return Collections.min(interfaceCandidates, TTypeComparator.INSTANCE);
				}
			}
		}
	}

	private static final int MAX_CACHE= 1024;
	private Map<TType, Boolean> fInterfaceTaggingCache= new LinkedHashMap<TType, Boolean>(MAX_CACHE, 0.75f, true) {
		private static final long serialVersionUID= 1L;
		@Override
		protected boolean removeEldestEntry(Map.Entry<TType, Boolean> eldest) {
			return size() > MAX_CACHE;
		}
	};

	private ArrayList<TType> getNonTaggingInterfaces(ArrayList<TType> interfaceCandidates) {
		ArrayList<TType> unresolvedTypes= new ArrayList<TType>();
		ArrayList<TType> nonTagging= new ArrayList<TType>();

		for (int i= 0; i < interfaceCandidates.size(); i++) {
			TType interf= interfaceCandidates.get(i);
			Object isTagging= fInterfaceTaggingCache.get(interf);
			if (isTagging == null)
				unresolvedTypes.add(interf);
			else if (isTagging == Boolean.FALSE)
				nonTagging.add(interf);
		}

		if (unresolvedTypes.size() != 0) {
			TType[] interfaces= unresolvedTypes.toArray(new TType[unresolvedTypes.size()]);
			for (int i= 0; i < interfaces.length; i++) {
				TType interf= interfaces[i];
				if (isTaggingInterface(interf)) {
					fInterfaceTaggingCache.put(interf, Boolean.TRUE);
				} else {
					fInterfaceTaggingCache.put(interf, Boolean.FALSE);
					nonTagging.add(interf);
				}
			}
		}

		return nonTagging;
	}

	private static boolean isTaggingInterface(TType interf) {
		if (interf instanceof HierarchyType) {
			try {
				return ((HierarchyType) interf).getJavaElementType().getMethods().length == 0;
			} catch (JavaModelException e) {
				// assume it's not
			}
		}
		return false;
	}

	private void findCastsToRemove(CastVariable2[] castVariables) {
		for (int i= 0; i < castVariables.length; i++) {
			CastVariable2 castCv= castVariables[i];
			ConstraintVariable2 expressionVariable= castCv.getExpressionVariable();
			TType chosenType= InferTypeArgumentsConstraintsSolver.getChosenType(expressionVariable);
			TType castType= castCv.getType();
			TType expressionType= expressionVariable.getType();
			if (chosenType != null && TTypes.canAssignTo(chosenType, castType)) {
				if (chosenType.equals(expressionType))
					continue; // The type has not changed. Don't remove the cast, since it could be
							   // there to get access to default-visible members or to
							   // unify types of conditional expressions.
				fUpdate.addCastToRemove(castCv);

			} else if (expressionVariable instanceof ArrayTypeVariable2 && castType.isArrayType()) { // bug 97258
				ArrayElementVariable2 arrayElementCv= fTCModel.getArrayElementVariable(expressionVariable);
				if (arrayElementCv == null)
					continue;
				TType chosenArrayElementType= InferTypeArgumentsConstraintsSolver.getChosenType(arrayElementCv);
				if (chosenArrayElementType != null && TTypes.canAssignTo(chosenArrayElementType, ((ArrayType) castType).getComponentType())) {
					if (expressionType instanceof ArrayType && chosenArrayElementType.equals(((ArrayType) expressionType).getComponentType()))
						continue; // The type has not changed. Don't remove the cast, since it could be
								   // there to unify types of conditional expressions.
					fUpdate.addCastToRemove(castCv);
				}
			}
		}
	}

	public static TType getChosenType(ConstraintVariable2 cv) {
		TType type= (TType) cv.getData(CHOSEN_TYPE);
		if (type != null)
			return type;
		TypeEquivalenceSet set= cv.getTypeEquivalenceSet();
		if (set == null) { //TODO: should not have to set this here. Clean up when caching chosen type
			return null;
//			// no representative == no restriction
//			set= new TypeEquivalenceSet(cv);
//			set.setTypeEstimate(TypeUniverseSet.create());
//			cv.setTypeEquivalenceSet(set);
		}
		return cv.getTypeEstimate().chooseSingleType();
	}

	private static void setChosenType(ConstraintVariable2 cv, TType type) {
		cv.setData(CHOSEN_TYPE, type);
	}
}
