package org.eclipse.cosmos.me.sdd.tooling.btg.aggregator.comparisons;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.cosmos.me.sdd.schema.ConditionalResourceConstraintType;
import org.eclipse.cosmos.me.sdd.schema.ObjectFactory;
import org.eclipse.cosmos.me.sdd.schema.ResourceType;

public class ConditionalResourceConstraintCompare
{
	
//	<ConditionalResourceConstraintType> 	 	 	 	
//	id 	xsd:ID 	Throw Away
//	resourceRef 	xsd:IDREF 	Yes
//	testValue 	xsd:boolean 	Yes
//	any 	namespace="##other" 	 ?
//DisplayElementGroup 		DisplayElementGroup 	Merge
//Name		<VariableExpressionType> 	Merge
//VersionConstraint		<VersionConstraintValueType> 	Merge
//PropertyConstraint 		<ConditionalPropertyConstraintType> 	Merge
//UniquenessConstraint 		<UniquenessConstraintType> 	Merge
//RelationshipConstraint 		<RelationshipConstraintType> 	Merge 

	protected static Vector<ConditionalResourceConstraintType> merge(List<ConditionalResourceConstraintType> rcs,	List<ConditionalResourceConstraintType> rcs2)
	{
		Vector <ConditionalResourceConstraintType> toRemove = new Vector <ConditionalResourceConstraintType> ();
		Iterator <ConditionalResourceConstraintType> iter1 = rcs.iterator();		
		//iterate through the items
		while (iter1.hasNext())
		{
			ConditionalResourceConstraintType o1 = (ConditionalResourceConstraintType) iter1.next();
			Iterator <ConditionalResourceConstraintType> iter2 = rcs2.iterator();
			while (iter2.hasNext())
			{
				ConditionalResourceConstraintType o2 = (ConditionalResourceConstraintType) iter2.next();
				//if you find a match that hasn't been found, note it
				//one of the equals needs to be deleted with its children merged over
				if (toRemove.contains(o2)==false)
				{
					if (equals(o1, o2))
					{  
						toRemove.add(o2);
						o1 = merge(o1,o2);
					}
				}
					
			}
		}
		
		rcs2.removeAll(toRemove);
		//remove all of the matches that were found
		
		Vector <ConditionalResourceConstraintType> finals = new Vector <ConditionalResourceConstraintType> ();
		//create and return a new collection with all of the remaining items
		finals.addAll(rcs);
		finals.addAll(rcs2);		
		
		return finals;
	}

	protected static ConditionalResourceConstraintType merge(ConditionalResourceConstraintType o1,	ConditionalResourceConstraintType o2)
	{
		ObjectFactory objectFactory = new ObjectFactory();
		ConditionalResourceConstraintType rc = objectFactory.createConditionalResourceConstraintType();
		rc.setDescription(DisplayTextCompare.merge(o1.getDescription(), o2.getDescription()));
		rc.setDisplayName(DisplayTextCompare.merge(o1.getDisplayName(), o2.getDisplayName()));
		rc.setId(o1.getId());
		rc.setName(StringCompare.merge(o1.getName(), o2.getName()));
		rc.getPropertyConstraint().addAll(ConditionalPropertyConstraintCompare.merge(o1.getPropertyConstraint(),o2.getPropertyConstraint()));
		rc.getRelationshipConstraint().addAll(RelationshipConstraintCompare.merge(o1.getRelationshipConstraint(),o2.getRelationshipConstraint()));
		rc.setShortDescription(DisplayTextCompare.merge(o1.getShortDescription(), o2.getShortDescription()));
		rc.getUniquenessConstraint().addAll(UniquenessConstraintCompare.merge(o1.getUniquenessConstraint(),o2.getUniquenessConstraint()));
		rc.setVersionConstraint(VersionConstraintValueCompare.merge(o1.getVersionConstraint(), o2.getVersionConstraint()));
		rc.setTestValue(o1.isTestValue());
		return rc;
	}

	protected static boolean equals(List<ConditionalResourceConstraintType> rc, List<ConditionalResourceConstraintType> rc2)
	{
		if (rc.size()!=rc2.size())
			return false;
		
		Iterator <ConditionalResourceConstraintType> iter = rc.iterator();
		
		while (iter.hasNext())
		{
			@SuppressWarnings("unused")
			ConditionalResourceConstraintType o = iter.next();
			
			Iterator <ConditionalResourceConstraintType> iterc2 = rc2.iterator();
			boolean notfound = true;
			ConditionalResourceConstraintType o2 = null;
			while (iterc2.hasNext()&&notfound)
			{
				o2 = iterc2.next();
				if (equals(rc,rc2))
					notfound = false;
			}
			if (notfound)
				return false;
			else
				rc2.remove(o2);
		}
		
		return true;
	}
	
	protected static boolean equals(ConditionalResourceConstraintType rc, ConditionalResourceConstraintType rc2)
	{
		if (!ResourceCompare.equals((ResourceType)rc.getResourceRef(),(ResourceType)rc2.getResourceRef()))
			return false;
		if (rc.isTestValue()!=rc2.isTestValue())
			return false;
		return true;
	}

}
