/*******************************************************************************
 * 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 java.util.Properties;

import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.DeploymentDescriptor;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.Resource;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.ResultingChangeMap;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.ResultingResource;

public class ResultingResourceType {
	/*
	 * <ResultingResourceType> 	 	 	 	
		resourceRef 	xsd:IDREF 	Yes
		any 	namespace="##other" 	 ?
		DescriptionGroup 		DescriptionGroup 	Merge
		Condition 		<ConditionType> 	Yes
		Name 		<VariableExpressionType> 	Merge
		Version 		<VersionType> 	Yes
		FixName 		xsd:string 	Merge
		Property 		<ResultingPropertyType> 	Merge
		Relationship 		<RelationshipType> 	Merge
		any 		namespace="##other" 	 ? 
	 */
	
	public static Collection <ResultingResource> merge (Collection <ResultingResource> resultingResources1, Collection <ResultingResource> resultingResources2)
	{
		Collection <ResultingResource> resultingResourcesToRemove = new ArrayList <ResultingResource> ();
		Iterator <ResultingResource> resultingResourceIter1 = resultingResources1.iterator();		
		//iterate through the resultingResources
		while (resultingResourceIter1.hasNext())
		{
			ResultingResource resultingResource1 = (ResultingResource) resultingResourceIter1.next();
			Iterator <ResultingResource> resultingResourceIter2 = resultingResources2.iterator();
			while (resultingResourceIter2.hasNext())
			{
				ResultingResource resultingResource2 = (ResultingResource) resultingResourceIter2.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 (resultingResourcesToRemove.contains(resultingResource2)==false)
				{
					if (equals(resultingResource1, resultingResource2))
					{  //merge hosted resultingResources, types and description groups
						resultingResourcesToRemove.add(resultingResource2);						
						resultingResource1 = merge(resultingResource1,resultingResource2);
						
					}
				}
					
			}
		}
		
		resultingResources2.removeAll(resultingResourcesToRemove);
		//remove all of the matches that were found
		
		Collection <ResultingResource> finalResultingResources = new ArrayList <ResultingResource> ();
		//create and return a new collection with all of the remaining items
		finalResultingResources.addAll(resultingResources1);
		finalResultingResources.addAll(resultingResources2);		
		
		return finalResultingResources;
	}
	
	public static boolean equals(ResultingResource resource1, ResultingResource resource2)
	{		
		Resource resourceRef1 = Util.resolveResourceRef(resource1.getResourceReference());
		Resource resourceRef2 = Util.resolveResourceRef(resource2.getResourceReference());
		
		if (!ResourceType.equals(resourceRef1, resourceRef2))
			return false;
		if ((resource1.getCondition()==null)&&(resource2.getCondition()!=null))
			return false;
		if ((resource1.getCondition()!=null)&&(resource2.getCondition()==null))
			return false;
		if ((resource1.getCondition()!=null)&&(resource2.getCondition()!=null))
		{
			if (!ConditionType.equals(resource1.getCondition(),resource2.getCondition()))
				return false;
		}
		
		if ((resource1.getVersion()==null)&&(resource2.getVersion()!=null))
			return false;
		if ((resource1.getVersion()!=null)&&(resource2.getVersion()==null))
			return false;
		if  ((resource1.getVersion()!=null)&&(resource2.getVersion()!=null))
		{						
		   if (!StringType.equals(resource1.getVersion(), resource2.getVersion()))
		       return false;
		}
			
		return true;
	}
	
	public static boolean equals(Collection <ResultingResource> resources1, Collection <ResultingResource> resources2)
	{		
		Iterator <ResultingResource> iter1 = resources1.iterator();
		
		while (iter1.hasNext())
		{
			ResultingResource resource1 = iter1.next();
			boolean match = false;
			Iterator <ResultingResource> iter2 = resources2.iterator();
			
			while ((iter2.hasNext())||(!match))
			{
				ResultingResource resource2 = iter2.next();
				if (equals(resource1,resource2))
				{
					match = true;
				}
			}
			if (!match)
				return false;			
		}
			
		return true;
	}
	
	public static ResultingResource merge (ResultingResource resource1, ResultingResource resource2)
	{
		resource1.setDescription(TranslatableStringType.merge(resource1.getDescription(),resource2.getDescription()));
		
		resource1.setShortDescription(TranslatableStringType.merge(resource1.getShortDescription(),resource2.getShortDescription()));
		
		resource1.setName(StringType.merge(resource1.getName(),resource2.getName()));
		resource1.setFixNames(StringType.merge(resource1.getFixNames(), resource2.getFixNames()));
		
		Properties myProps = resource1.getProperties();
		myProps.putAll(resource2.getProperties());
		resource1.setProperties(myProps);
		//NO RELATIONSHIPS For this type in spi
		
		return resource1;
	}
	

}
