/*******************************************************************************
 * 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.ResultingResourceMap;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.CompositeInstallable;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.InstallableUnit;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.Language;
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.variable.DerivedVariable;



public class ResultingResourceMapType {

	public static Collection <ResultingResourceMap> merge(Collection <ResultingResourceMap> resultingResourceMaps1, Collection <ResultingResourceMap> resultingResourceMaps2)
	{
		// set to hold all the merged variables
		Collection <ResultingResourceMap> resultingResourceMapsToRemove = new ArrayList <ResultingResourceMap> ();
		Iterator <ResultingResourceMap> resultingResourceMapIter1 = resultingResourceMaps1.iterator();		
		//iterate through the resultingResourceMaps
		while (resultingResourceMapIter1.hasNext())
		{
			ResultingResourceMap resultingResourceMap1 = (ResultingResourceMap) resultingResourceMapIter1.next();
			Iterator <ResultingResourceMap> resultingResourceMapIter2 = resultingResourceMaps2.iterator();
			while (resultingResourceMapIter2.hasNext())
			{
				ResultingResourceMap resultingResourceMap2 = (ResultingResourceMap) resultingResourceMapIter2.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 (resultingResourceMapsToRemove.contains(resultingResourceMap2)==false)
				{
					if (equals(resultingResourceMap1, resultingResourceMap2))
					{  //merge hosted resultingResourceMaps, types and description resultingResourceMaps
						resultingResourceMapsToRemove.add(resultingResourceMap2);						
						resultingResourceMap1 = merge(resultingResourceMap1,resultingResourceMap2);						
					}
				}
					
			}
		}
		
		resultingResourceMaps2.removeAll(resultingResourceMapsToRemove);
		//remove all of the matches that were found
		
		Collection <ResultingResourceMap> finalResultingResourceMaps = new ArrayList <ResultingResourceMap> ();
		//create and return a new collection with all of the remaining items
		finalResultingResourceMaps.addAll(resultingResourceMaps1);
		finalResultingResourceMaps.addAll(resultingResourceMaps2);		
		
		return finalResultingResourceMaps;
		
	}
	
	private static ResultingResourceMap merge(ResultingResourceMap resultingResourceMap1, ResultingResourceMap resultingResourceMap2)
	{
		resultingResourceMap1.setName(StringType.merge(resultingResourceMap1.getName(), resultingResourceMap2.getName()));
		resultingResourceMap1.setFixNames(StringType.merge(resultingResourceMap1.getFixNames(), resultingResourceMap2.getFixNames()));
		
		Properties myProps = resultingResourceMap1.getProperties();
		myProps.putAll(resultingResourceMap2.getProperties());
		resultingResourceMap1.setProperties(myProps);
		
		resultingResourceMap1.setRelationships(RelationshipType.merge(resultingResourceMap1.getRelationships(), resultingResourceMap2.getRelationships()));
		
		return resultingResourceMap1;
	}

	public static boolean equals(ResultingResourceMap resultingResourceMap1, ResultingResourceMap resultingResourceMap2)
	{
		if ((resultingResourceMap1.getCondition()!=null)&&(resultingResourceMap2.getCondition()==null))
			return false;
		if ((resultingResourceMap2.getCondition()!=null)&&(resultingResourceMap1.getCondition()==null))
			return false;
		if ((resultingResourceMap1.getCondition()!=null)&&(resultingResourceMap2.getCondition()==null))
		{
			if (!ConditionType.equals(resultingResourceMap1.getCondition(), resultingResourceMap2.getCondition()))
				return false;
		}
		
		if ((resultingResourceMap1.getVersion()!=null)&&(resultingResourceMap2.getVersion()==null))
			return false;
		if ((resultingResourceMap2.getVersion()!=null)&&(resultingResourceMap1.getVersion()==null))
			return false;
		if ((resultingResourceMap1.getVersion()!=null)&&(resultingResourceMap2.getVersion()==null))
		{
			if (!VersionType.equals(resultingResourceMap1.getVersion(), resultingResourceMap2.getVersion()))
				return false;
		}
		
		return true;
		
	}
	
}
