/*******************************************************************************
 * 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:
 *   Robert M. Fuhrer (rfuhrer@watson.ibm.com), IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets;

import java.util.Iterator;

import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ArrayType;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TTypes;

public class SuperTypesSet extends TypeSet {
	private TypeSet fLowerBounds;

	SuperTypesSet(TType subType, TypeSetEnvironment typeSetEnvironment) {
		super(typeSetEnvironment);
		fLowerBounds= new SingletonTypeSet(subType, typeSetEnvironment);
	}

	SuperTypesSet(TypeSet subTypes, TypeSetEnvironment typeSetEnvironment) {
		super(typeSetEnvironment);
		fLowerBounds= subTypes;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isUniverse()
	 */
	@Override
	public boolean isUniverse() {
		return fLowerBounds.isUniverse();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#makeClone()
	 */
	@Override
	public TypeSet makeClone() {
		return this; //new SuperTypesSet(fLowerBounds.makeClone(), getTypeSetEnvironment());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#upperBound()
	 */
	@Override
	public TypeSet upperBound() {
		return new SingletonTypeSet(getTypeSetEnvironment().getJavaLangObject(), getTypeSetEnvironment());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#lowerBound()
	 */
	@Override
	public TypeSet lowerBound() {
		// Ask the operand for its lower-bound, in case it's something like an
		// EnumeratedTypeSet, which may have things in it other than the lower
		// bound...
		return fLowerBounds.lowerBound();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#intersectedWith(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.EnumeratedTypeSet)
	 */
	@Override
	protected TypeSet specialCasesIntersectedWith(TypeSet s2) {
		if (fLowerBounds.equals(s2))
			return s2; // xsect(superTypes(A),A) = A
		if (s2 instanceof SuperTypesSet) {
			SuperTypesSet st2= (SuperTypesSet) s2;

			if (fLowerBounds.isSingleton() && st2.fLowerBounds.isSingleton()) {
				TType t1= this.fLowerBounds.anyMember();
				TType t2= st2.fLowerBounds.anyMember();

				if (TTypes.canAssignTo(t1, t2))
					return new SuperTypesSet(st2.fLowerBounds, getTypeSetEnvironment());
			} else if (fLowerBounds instanceof SubTypesSet) {
				// xsect(superTypes(subTypes(A)), superTypes(A)) = superTypes(A)
				SubTypesSet myLowerSubTypes= (SubTypesSet) fLowerBounds;

				if (myLowerSubTypes.upperBound().equals(st2.upperBound()))
					return st2;
			}
		}
		if (s2 instanceof SuperTypesOfSingleton) {
			SuperTypesOfSingleton st2= (SuperTypesOfSingleton) s2;

			if (fLowerBounds.isSingleton()) {
				TType t1= this.fLowerBounds.anyMember();
				TType t2= st2.uniqueLowerBound();

				if (TTypes.canAssignTo(t1, t2))
					return getTypeSetEnvironment().createSuperTypesOfSingleton(t2);
			} else if (fLowerBounds instanceof SubTypesOfSingleton) {
				// xsect(superTypes(subTypes(A)), superTypes(A)) = superTypes(A)
				SubTypesOfSingleton myLowerSubTypes= (SubTypesOfSingleton) fLowerBounds;

				if (myLowerSubTypes.uniqueUpperBound().equals(st2.uniqueUpperBound()))
					return st2;
			}
		}
		if (s2 instanceof SubTypesSet) {
			SubTypesSet st2= (SubTypesSet) s2;
			if (fLowerBounds.equals(st2.upperBound()))
				return fLowerBounds;

			if (fLowerBounds instanceof TypeSetIntersection) {
				// (intersect (superTypes (intersect (subTypes A) B))
				//            (subTypes A)) =>
				// (intersect (subTypes A) (superTypes B))
				TypeSetIntersection lbXSect= (TypeSetIntersection) fLowerBounds;
				TypeSet xsectLeft= lbXSect.getLHS();
				TypeSet xsectRight= lbXSect.getRHS();

				if (xsectLeft.equals(st2.upperBound()))
					return new TypeSetIntersection(s2, new SuperTypesSet(xsectRight, getTypeSetEnvironment()));
			}
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#superTypes()
	 */
	@Override
	public TypeSet superTypes() {
		return this; // makeClone();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isEmpty()
	 */
	@Override
	public boolean isEmpty() {
		return fLowerBounds.isEmpty();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#contains(TType)
	 */
	@Override
	public boolean contains(TType t) {
		if (fEnumCache != null) return fEnumCache.contains(t);

		if (t.equals(getJavaLangObject()))
			return true;
		if (fLowerBounds.contains(t))
			return true;

		// Find the "lower frontier", i.e. the lower bound, and see whether
		// the given type is a supertype of any of those.
		for(Iterator<TType> lbIter= fLowerBounds /*.lowerBound() */.iterator(); lbIter.hasNext(); ) {
			TType lb= lbIter.next();

			if (TTypes.canAssignTo(lb, t))
				return true;
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#containsAll(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.EnumeratedTypeSet)
	 */
	@Override
	public boolean containsAll(TypeSet s) {
		if (fEnumCache != null) return fEnumCache.containsAll(s);

		if (!isUniverse() && s.isUniverse()) // this is more general than just SuperTypesSet; probably belongs in TypeSet
			return false;
		if (equals(s))
			return true;
		if (fLowerBounds.containsAll(s))
			return true;

		// Make sure all elements of s are contained in this set
		for(Iterator<TType> sIter= s.iterator(); sIter.hasNext(); ) {
			TType t= sIter.next();
			boolean found= false;

			// Scan the "lower frontier", i.e. the lower bound set, and see whether
			// 't' is a supertype of any of those.
			for(Iterator<TType> lbIter= fLowerBounds /*.lowerBound()*/.iterator(); lbIter.hasNext(); ) {
				TType lb= lbIter.next();

				if (TTypes.canAssignTo(lb, t)) {
					found= true;
					break;
				}
			}
			if (!found) return false;
		}
		return true;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isSingleton()
	 */
	@Override
	public boolean isSingleton() {
		if (fEnumCache != null) return fEnumCache.isSingleton();

		return fLowerBounds.isSingleton() && (fLowerBounds.anyMember() == getJavaLangObject());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#anyMember()
	 */
	@Override
	public TType anyMember() {
		return fLowerBounds.anyMember();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object o) {
		if (o instanceof SuperTypesSet) {
			SuperTypesSet other= (SuperTypesSet) o;
			return other.fLowerBounds.equals(fLowerBounds);
//		} else if (o instanceof TypeSet) {
//			TypeSet other= (TypeSet) o;
//			if (other.isUniverse() && isUniverse())
//				return true;
//			return enumerate().equals(other.enumerate());
		} else
			return false;
	}

	@Override
	public int hashCode() {
		return fLowerBounds.hashCode();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#iterator()
	 */
	@Override
	public Iterator<TType> iterator() {
		return enumerate().iterator();
	}

	@Override
	public String toString() {
		return "<" + fID + ": superTypes(" + fLowerBounds + ")>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueLowerBound()
	 */
	@Override
	public boolean hasUniqueLowerBound() {
		return fLowerBounds.isSingleton();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueUpperBound()
	 */
	@Override
	public boolean hasUniqueUpperBound() {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueLowerBound()
	 */
	@Override
	public TType uniqueLowerBound() {
		return fLowerBounds.isSingleton() ? fLowerBounds.anyMember() : null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueUpperBound()
	 */
	@Override
	public TType uniqueUpperBound() {
		return null;
	}

	private EnumeratedTypeSet fEnumCache= null;

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#enumerate()
	 */
	@Override
	public EnumeratedTypeSet enumerate() {
		if (fEnumCache == null) {
			fEnumCache= new EnumeratedTypeSet(getTypeSetEnvironment());
			boolean anyLBIsIntfOrArray= false;

			for(Iterator<TType> iter= fLowerBounds.iterator(); iter.hasNext(); ) {
				TType lb= iter.next();

				if (lb instanceof ArrayType) {
					ArrayType at= (ArrayType) lb;
					int numDims= at.getDimensions();
					for(Iterator<TType> elemSuperIter=TTypes.getAllSuperTypesIterator(at.getElementType()); elemSuperIter.hasNext(); )
						fEnumCache.add(TTypes.createArrayType(elemSuperIter.next(), numDims));
					anyLBIsIntfOrArray= true;
				} else {
					for (Iterator<TType> iterator= TTypes.getAllSuperTypesIterator(lb); iterator.hasNext(); )
					fEnumCache.fMembers.add(iterator.next());
				}
				fEnumCache.add(lb);
			}
			if (anyLBIsIntfOrArray) fEnumCache.add(getJavaLangObject());
			//fEnumCache.initComplete();
		}
		return fEnumCache;
	}
}
