/*******************************************************************************
 * Copyright (c) 2000, 2006 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.IJavaProject;
import org.eclipse.jdt.core.dom.ITypeBinding;

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.types.TypeEnvironment;
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 {
		public int compare(Object o1, Object o2) {
			return ((TType) o1).getPrettySignature().compareTo(((TType) 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();
	}
	
	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 newAllConstraintVariables= new ArrayList();
		newAllConstraintVariables.addAll(Arrays.asList(allConstraintVariables));
		newAllConstraintVariables.addAll(newVars);
		allConstraintVariables= (ConstraintVariable2[]) newAllConstraintVariables.toArray(new ConstraintVariable2[newAllConstraintVariables.size()]);
		
		
		//loop over all TypeEquivalenceSets and unify the elements from the fElemStructureEnv with the existing TypeEquivalenceSets
		HashSet allTypeEquivalenceSets= new HashSet();
		for (int i= 0; i < allConstraintVariables.length; i++) {
			TypeEquivalenceSet typeEquivalenceSet= allConstraintVariables[i].getTypeEquivalenceSet();
			if (typeEquivalenceSet != null)
				allTypeEquivalenceSets.add(typeEquivalenceSet);
		}
		for (Iterator iter= allTypeEquivalenceSets.iterator(); iter.hasNext();) {
			TypeEquivalenceSet 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= (ConstraintVariable2) fWorkList.removeFirst();
			List/*<ITypeConstraint2>*/ usedIn= fTCModel.getUsedIn(cv);
			processConstraints(usedIn, cv);
			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
	 * @param changedCv the constraint variable whose type bound has changed
	 */
	private void processConstraints(List/*<ITypeConstraint2>*/ usedIn, ConstraintVariable2 changedCv) {
		int i= 0;
		for (Iterator iter= usedIn.iterator(); iter.hasNext(); i++) {
			ITypeConstraint2 tc= (ITypeConstraint2) iter.next();

				maintainSimpleConstraint(changedCv, 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(ConstraintVariable2 changedCv, 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 iter= lowerBound.iterator(); iter.hasNext();) {
				TType type= (TType) iter.next();
				if (! type.isInterface()) {
					return type;
				} else {
					if (interfaceCandidates == null)
						interfaceCandidates= new ArrayList(2);
					interfaceCandidates.add(type);
				}
			}
			
			if (interfaceCandidates == null || interfaceCandidates.size() == 0) {
				return null;
			} else if (interfaceCandidates.size() == 1) {
				return (TType) interfaceCandidates.get(0);
			} else {
				ArrayList nontaggingCandidates= getNonTaggingInterfaces(interfaceCandidates);
				if (nontaggingCandidates.size() != 0) {
					return (TType) Collections.min(nontaggingCandidates, TTypeComparator.INSTANCE);
				} else {
					return (TType) Collections.min(interfaceCandidates, TTypeComparator.INSTANCE);
				}
			}
		}
	}

	private static final int MAX_CACHE= 1024;
	private Map/*<TType, Boolean>*/ fInterfaceTaggingCache= new LinkedHashMap(MAX_CACHE, 0.75f, true) {
		private static final long serialVersionUID= 1L;
		protected boolean removeEldestEntry(Map.Entry eldest) {
			return size() > MAX_CACHE;
		}
	};
	
	private ArrayList getNonTaggingInterfaces(ArrayList interfaceCandidates) {
		ArrayList unresolvedTypes= new ArrayList();
		ArrayList nonTagging= new ArrayList();
		
		for (int i= 0; i < interfaceCandidates.size(); i++) {
			TType interf= (TType) 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= (TType[]) unresolvedTypes.toArray(new TType[unresolvedTypes.size()]);
			HierarchyType firstInterface= (HierarchyType) interfaces[0];
			IJavaProject javaProject= firstInterface.getJavaElementType().getJavaProject();
			ITypeBinding[] interfaceBindings= TypeEnvironment.createTypeBindings(interfaces, javaProject); //expensive...
			for (int i= 0; i < interfaceBindings.length; i++) {
				if (interfaceBindings[i].getDeclaredMethods().length == 0) {
					fInterfaceTaggingCache.put(interfaces[i], Boolean.TRUE);
				} else {
					fInterfaceTaggingCache.put(interfaces[i], Boolean.FALSE);
					nonTagging.add(interfaces[i]);
				}
			}
		}
		
		return nonTagging;
	}

	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);
	}
}
