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

import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.DeploymentDescriptor;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.CompositeLocalizationUnit;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.Group;
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.variable.DerivedVariable;



public class GroupType {
	
	/*
		  <GroupType>

			<xsd:complexType name="GroupType">
			  <xsd:sequence>
			    <xsd:group ref="sdd-dd:DisplayElementGroup" minOccurs="0"/>
			    <xsd:element name="SelectedFeature" type="sdd-dd:FeatureReferenceType" maxOccurs="unbounded"/>
			    <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
			  </xsd:sequence>
			  <xsd:attribute name="id" type="xsd:ID" use="required"/>
			  <xsd:attribute name="default" type="xsd:boolean" use="optional" default="false"/>
			  <xsd:anyAttribute namespace="##other" processContents="lax"/>
			</xsd:complexType>

			Type 	Element 	Attribute 	Data Type 	Compare?
			<GroupType> 				
					id 	xsd:ID 	Throw Away
					default 	xsd:boolean 	Merge
					any 	namespace="##other" 	 ?
				DisplayElementGroup 		DisplayElementGroup 	Merge
				SelectedFeature 		<FeatureReferenceType> 	Yes
				any 		namespace="##other" 	 ? 
	*/
	
	public static Collection <Group> merge(Collection <Group> groups1, Collection <Group> groups2)
	{
		// set to hold all the merged variables
		Collection <Group> groupsToRemove = new ArrayList <Group> ();
		Iterator <Group> groupIter1 = groups1.iterator();		
		//iterate through the groups
		while (groupIter1.hasNext())
		{
			Group group1 = (Group) groupIter1.next();
			Iterator <Group> groupIter2 = groups2.iterator();
			while (groupIter2.hasNext())
			{
				Group group2 = (Group) groupIter2.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 (groupsToRemove.contains(group2)==false)
				{
					if (equals(group1, group2))
					{  //merge hosted groups, types and description groups
						groupsToRemove.add(group2);						
						group1 = merge(group1,group2);						
					}
				}
					
			}
		}
		
		groups2.removeAll(groupsToRemove);
		//remove all of the matches that were found
		
		Collection <Group> finalGroups = new ArrayList <Group> ();
		//create and return a new collection with all of the remaining items
		finalGroups.addAll(groups1);
		finalGroups.addAll(groups2);		
		
		return finalGroups;
	
	}
	
	public static boolean equals(Group group1, Group group2)
	{
		Set<String> features1  = new HashSet<String>(group1.getSelectedFeatures());
		Set<String> features2  = new HashSet<String>(group2.getSelectedFeatures());
		
		// AbstractSet.equals() does a element by element compare, exactly
		// what we need here
		
		return features1.equals(features2);	
		
	}
	
	public static Group merge(Group group1, Group group2)
	{
		
		group1.setDefault(group1.getDefault()||group2.getDefault());
		group1.setDescription(TranslatableStringType.merge(group1.getDescription(),group2.getDescription()));
		group1.setDisplayName(TranslatableStringType.merge(group1.getDisplayName(),group2.getDisplayName()));
		group1.setShortDescription(TranslatableStringType.merge(group1.getShortDescription(),group2.getShortDescription()));
		return group1;	
		
	}
	
}
