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.InternalDependencyType;
import org.eclipse.cosmos.me.sdd.schema.ObjectFactory;
import org.eclipse.cosmos.me.sdd.schema.RequirementResourceConstraintType;
import org.eclipse.cosmos.me.sdd.schema.RequirementType;

public class RequirementCompare
{

	protected static Vector<RequirementType> merge(List<RequirementType> rs,
			List<RequirementType> rs2)
	{
		Vector <RequirementType> toRemove = new Vector <RequirementType> ();
		Iterator <RequirementType> iter1 = rs.iterator();		
		//iterate through the items
		while (iter1.hasNext())
		{
			RequirementType o1 = (RequirementType) iter1.next();
			Iterator <RequirementType> iter2 = rs2.iterator();
			while (iter2.hasNext())
			{
				RequirementType o2 = (RequirementType) 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);
					}
				}
					
			}
		}
		
		rs2.removeAll(toRemove);
		//remove all of the matches that were found
		
		Vector <RequirementType> finals = new Vector <RequirementType> ();
		//create and return a new collection with all of the remaining items
		finals.addAll(rs);
		finals.addAll(rs2);		
		
		return finals;
	}
	
//	<RequirementType> 	 	 	 	
//	id 	xsd:ID 	Throw Away
//	operation 	<OperationListType> 	Yes
//	any 	namespace="##other" 	 ?
//DisplayElementGroup 		DisplayElementGroup 	Merge
//Alternative 		<AlternativeRequirementType> 	Merge
//ResourceConstraint 		<RequirementResourceConstraintType> 	Yes
//Dependency 		<InternalDependencyType> 	Yes
//any 		namespace="##other" 	 ? 

	protected static RequirementType merge(RequirementType o1,	RequirementType o2)
	{
		ObjectFactory objectFactory = new ObjectFactory();
		RequirementType r = objectFactory.createRequirementType();
		r.setDescription(DisplayTextCompare.merge(o1.getDescription(), o2.getDescription()));
		r.setDisplayName(DisplayTextCompare.merge(o1.getDisplayName(), o2.getDisplayName()));
		r.setId(o1.getId());
		r.getOperation().addAll(o1.getOperation());
		r.getAlternative().addAll(AlternativeRequirementCompare.merge(o1.getAlternative(),o2.getAlternative()));
		r.getResourceConstraintOrDependencyOrAny().addAll(o1.getResourceConstraintOrDependencyOrAny());
		r.setShortDescription(DisplayTextCompare.merge(o1.getShortDescription(), o2.getShortDescription()));
		
		return r;
	}
	
	protected static boolean equals(RequirementType r, RequirementType r2)
	{
		if (!OperationCompare.equals(r.getOperation(),r2.getOperation()))
			return false;
		
		Vector<RequirementResourceConstraintType> rcs = new Vector <RequirementResourceConstraintType>();
		Vector<RequirementResourceConstraintType> rcs2 = new Vector <RequirementResourceConstraintType>();
		Vector<InternalDependencyType> ids = new Vector <InternalDependencyType>();
		Vector<InternalDependencyType> ids2 = new Vector <InternalDependencyType>();
		
		Iterator <Object> iter = r.getResourceConstraintOrDependencyOrAny().iterator();
		
		while (iter.hasNext())
		{
			Object o = iter.next();
			if (o instanceof RequirementResourceConstraintType)
				rcs.add((RequirementResourceConstraintType)o);
			if (o instanceof InternalDependencyType)
				ids.add((InternalDependencyType)o);
		}
		
		Iterator <Object> iter2 = r2.getResourceConstraintOrDependencyOrAny().iterator();
		
		while (iter2.hasNext())
		{
			Object o = iter2.next();
			if (o instanceof RequirementResourceConstraintType)
				rcs2.add((RequirementResourceConstraintType)o);
			if (o instanceof InternalDependencyType)
				ids2.add((InternalDependencyType)o);
		}
		
		if (!InternalDependencyCompare.equals(ids,ids2))
			return false;
		
		return true;
	}

}
