/*******************************************************************************
 * Copyright (c) 2008 SAS Institute Inc.
 * 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:
 *     SAS Institute Inc. - initial API and implementation
 ******************************************************************************/
package org.eclipse.cosmos.me.provisional.deployment.sdd.tooling.btg.aggregator;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;


import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.Resource;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.TranslatableString;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.requiredbase.AlternativeRequiredBaseConstraint;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.requiredbase.RequiredBaseConstraint;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.requirement.AlternativeRequirement;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.requirement.Requirement;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.requirement.RequirementResourceConstraint;



public class AlternativeRequiredBaseConstraintType {

	/*
	 *<AlternativeRequiredBaseConstraintType> 	 	 	 	
		id 	xsd:ID 	Throw Away
		priority 	xsd:positiveInteger 	Merge
		any 	namespace="##other" 	 ?
	DisplayElementGroup 		DisplayElementGroup 	Merge
	ResourceConstraint 		<RequiredBaseConstraintType> 	Yes
	any 		namespace="##other" 	 ? 
	*/
	public static AlternativeRequiredBaseConstraint merge(AlternativeRequiredBaseConstraint constraint1, AlternativeRequiredBaseConstraint constraint2)	 
	{	
		
		if ((constraint1.getPriority()==null)&&(constraint2.getPriority()!=null))
			constraint1.setPriority(constraint2.getPriority());
		else if (constraint2.getPriority()!=null)
		{			
			if (constraint1.getPriority().compareTo(constraint2.getPriority())<0)
				constraint1.setPriority(constraint2.getPriority());			
		}
		
		constraint1.setDescription(TranslatableStringType.merge(constraint1.getDescription(), constraint2.getDescription()));
				
		constraint1.setDisplayName(TranslatableStringType.merge(constraint1.getDisplayName(), constraint2.getDisplayName()));
		
		return constraint1;
		
	}
	
	public static Collection <AlternativeRequiredBaseConstraint> merge(Collection <AlternativeRequiredBaseConstraint> alternativeRequiredBaseConstraints1, Collection <AlternativeRequiredBaseConstraint> alternativeRequiredBaseConstraints2)
	{
		Collection <AlternativeRequiredBaseConstraint> alternativeRequiredBaseConstraintsToRemove = new ArrayList <AlternativeRequiredBaseConstraint> ();
		Iterator <AlternativeRequiredBaseConstraint> alternativeRequiredBaseConstraintIter1 = alternativeRequiredBaseConstraints1.iterator();		
		//iterate through the alternativeRequiredBaseConstraints
		while (alternativeRequiredBaseConstraintIter1.hasNext())
		{
			AlternativeRequiredBaseConstraint alternativeRequiredBaseConstraint1 = (AlternativeRequiredBaseConstraint) alternativeRequiredBaseConstraintIter1.next();
			Iterator <AlternativeRequiredBaseConstraint> alternativeRequiredBaseConstraintIter2 = alternativeRequiredBaseConstraints2.iterator();
			while (alternativeRequiredBaseConstraintIter2.hasNext())
			{
				AlternativeRequiredBaseConstraint alternativeRequiredBaseConstraint2 = (AlternativeRequiredBaseConstraint) alternativeRequiredBaseConstraintIter2.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 (alternativeRequiredBaseConstraintsToRemove.contains(alternativeRequiredBaseConstraint2)==false)
				{
					if (equals(alternativeRequiredBaseConstraint1, alternativeRequiredBaseConstraint2))
					{  //merge hosted alternativeRequiredBaseConstraints, types and description groups
						alternativeRequiredBaseConstraintsToRemove.add(alternativeRequiredBaseConstraint2);						
						alternativeRequiredBaseConstraint1 = merge(alternativeRequiredBaseConstraint1,alternativeRequiredBaseConstraint2);
						
					}
				}
					
			}
		}
		
		alternativeRequiredBaseConstraints2.removeAll(alternativeRequiredBaseConstraintsToRemove);
		//remove all of the matches that were found
		
		Collection <AlternativeRequiredBaseConstraint> finalAlternativeRequiredBaseConstraints = new ArrayList <AlternativeRequiredBaseConstraint> ();
		//create and return a new collection with all of the remaining items
		finalAlternativeRequiredBaseConstraints.addAll(alternativeRequiredBaseConstraints1);
		finalAlternativeRequiredBaseConstraints.addAll(alternativeRequiredBaseConstraints2);		
		
		return finalAlternativeRequiredBaseConstraints;
		
	}
	
	public static boolean equals(AlternativeRequiredBaseConstraint constraint1, AlternativeRequiredBaseConstraint constraint2)
	{		
		boolean equals = true;
		
		Collection<RequiredBaseConstraint> requiredBaseConstraints1 = constraint1.getRequiredBaseConstraints();
		Collection<RequiredBaseConstraint> requiredBaseConstraints2 = constraint2.getRequiredBaseConstraints();
		
		Iterator<RequiredBaseConstraint> constraintsIter1 = requiredBaseConstraints1.iterator();	
		
		while ((constraintsIter1.hasNext())&&(equals))
		{
			RequiredBaseConstraint baseConstraint1 = constraintsIter1.next();
			
			Iterator<RequiredBaseConstraint> constraintsIter2 = requiredBaseConstraints2.iterator();
			while (constraintsIter2.hasNext())
			{
				RequiredBaseConstraint baseConstraint2 = constraintsIter2.next();				
				if ((RequiredBaseConstraintType.equals(baseConstraint1, baseConstraint2))==false)
				{
					equals=false;
				}				
			}
		}
		
		return equals;
		
	}
}

