/*******************************************************************************
 * 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.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.DeploymentDescriptor;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.ReferencedPackage;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.CompositeInstallable;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.CompositeUnit;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.InstallableUnit;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.LocalizationUnit;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.ConfigurationUnit;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.ResultingResource;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.requirement.RelationshipConstraint;



public class RelationshipConstraintType {
	
	/*
	 *   <RelationshipConstraintType>

		<xsd:complexType name="RelationshipConstraintType">
		  <xsd:sequence>
		    <xsd:group ref="sdd-dd:DescriptionGroup" minOccurs="0"/>
		    <xsd:element name="Property" type="sdd-dd:PropertyType" minOccurs="0" maxOccurs="unbounded"/>
		  </xsd:sequence>
		  <xsd:attribute name="relatedResourceRef" type="xsd:IDREF" use="optional"/>
		  <xsd:attribute name="type" type="xsd:QName" use="required"/>
		  <xsd:anyAttribute namespace="##other" processContents="lax"/>
		</xsd:complexType>
		
		Type 	Element 	Attribute 	Data Type 	Compare?
		<RelationshipConstraintType> 				
				relatedResourceRef 	xsd:IDREF 	Yes
				type 	xsd:QName 	Yes
				any 	namespace="##other" 	 ?
			DescriptionGroup 		DescriptionGroup 	Merge
			Property 		<PropertyType> 	Yes
		
		Notes:
		The comparison of relatedResourceRef involves comparing the Resource pointed to, not the reference itself. 
	 */
	
	
	public static Collection <RelationshipConstraint> merge(Collection <RelationshipConstraint> relationshipConstraints1, Collection <RelationshipConstraint> relationshipConstraints2)
	{
		Collection <RelationshipConstraint> relationshipConstraintsToRemove = new ArrayList <RelationshipConstraint> ();
		Iterator <RelationshipConstraint> relationshipConstraintIter1 = relationshipConstraints1.iterator();		
		//iterate through the relationshipConstraints
		while (relationshipConstraintIter1.hasNext())
		{
			RelationshipConstraint relationshipConstraint1 = (RelationshipConstraint) relationshipConstraintIter1.next();
			Iterator <RelationshipConstraint> relationshipConstraintIter2 = relationshipConstraints2.iterator();
			while (relationshipConstraintIter2.hasNext())
			{
				RelationshipConstraint relationshipConstraint2 = (RelationshipConstraint) relationshipConstraintIter2.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 (relationshipConstraintsToRemove.contains(relationshipConstraint2)==false)
				{
					if (equals(relationshipConstraint1, relationshipConstraint2))
					{  //merge hosted relationshipConstraints, types and description groups
						relationshipConstraintsToRemove.add(relationshipConstraint2);						
						relationshipConstraint1 = merge(relationshipConstraint1,relationshipConstraint2);
						
					}
				}
					
			}
		}
		
		relationshipConstraints2.removeAll(relationshipConstraintsToRemove);
		//remove all of the matches that were found
		
		Collection <RelationshipConstraint> finalRelationshipConstraints = new ArrayList <RelationshipConstraint> ();
		//create and return a new collection with all of the remaining items
		finalRelationshipConstraints.addAll(relationshipConstraints1);
		finalRelationshipConstraints.addAll(relationshipConstraints2);		
		
		return finalRelationshipConstraints;
	}
	
	
	public static RelationshipConstraint merge(RelationshipConstraint relationshipConstraint1,	RelationshipConstraint relationshipConstraint2)
	{		
		relationshipConstraint1.setDescription(TranslatableStringType.merge(relationshipConstraint1.getDescription(),relationshipConstraint2.getDescription()));		
		relationshipConstraint1.setShortDescription(TranslatableStringType.merge(relationshipConstraint1.getShortDescription(),relationshipConstraint2.getShortDescription()));
		return relationshipConstraint1;	
	}


	public static boolean equals(RelationshipConstraint constraint1, RelationshipConstraint constraint2)
	{
		if ((constraint1.getRelatedResourceReference()!=null)&&(constraint2.getRelatedResourceReference()==null))
			return false;
		if ((constraint2.getRelatedResourceReference()!=null)&&(constraint1.getRelatedResourceReference()==null))
			return false;
		
		if ((constraint2.getRelatedResourceReference()!=null)&&(constraint1.getRelatedResourceReference()!=null))
			if (ResourceType.equals(Util.resolveResourceRef(constraint1.getRelatedResourceReference()),Util.resolveResourceRef(constraint2.getRelatedResourceReference())))
				if (StringType.equals(constraint1.getType(), constraint2.getType()))
					if (PropertyType.equals(constraint1.getProperties(),constraint2.getProperties()))
						return true;
		
		return false;						
	}
	
	

	
}
