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

import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.BaseFactory;
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.SPISession;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.TranslatableString;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.artifact.AdditionalContent;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.artifact.Artifact;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.artifact.ArtifactFactory;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.CompositeInstallable;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.ContentUnitFactory;
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;



public class DeploymentDescriptorType {
	
	public static DeploymentDescriptor merge(DeploymentDescriptor dd1, DeploymentDescriptor dd2)
	{
		DeploymentDescriptor finaldd = dd1;
		/*DescriptorInfoGroup 	 DescriptorInfoGroup 	 Merge
	Topology 		<TopologyType> 	Merge
	InstallableUnit 		<InstallableUnitType> 	Merge
	ConfigurationUnit 		<ConfigurationUnitType> 	Merge
	LocalizationUnit 		<LocalizationUnitType> 	Merge
	CompositeInstallable 		<CompositeInstallableType> 	Merge
	Requisites 		<RequisitesType> 	Merge 
	*/
		//compare Descriptorinfogroup
		
		
		
		finaldd.setResources(TopologyType.merge(dd1.getResources(), dd2.getResources()));
		
		
		if ((dd1.getContentUnit()==null)&&(dd2.getContentUnit()!=null))
		{
			
			SPISession session = SPISession.DEFAULT_INSTANCE;
			
			ContentUnitFactory cuFactory = session.createContentUnitFactory();
			
			CompositeInstallable compInstall = null;
			
			if (dd2.getContentUnit() instanceof InstallableUnit)
			{
				compInstall = cuFactory.createCompositeInstallable(dd2.getContentUnit().getContentUnitID(), "install");
				Collection <InstallableUnit> iUs = new ArrayList <InstallableUnit> ();
				iUs.add((InstallableUnit)dd2.getContentUnit());
				compInstall.setBaseInstallableUnits(iUs);
				Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();
				compInstalls = dd1.getCompositeInstallables();
				compInstalls.add(compInstall);
				dd1.setCompositeInstallables(compInstalls);
			}
						
						 
			if (dd2.getContentUnit() instanceof LocalizationUnit)			
			{
				compInstall = cuFactory.createCompositeInstallable(dd2.getContentUnit().getContentUnitID(), "localization");
				Collection <LocalizationUnit> lUs = new ArrayList <LocalizationUnit> ();
				lUs.add((LocalizationUnit)dd2.getContentUnit());
				compInstall.setLocalizationUnits(lUs);				
				Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();
				compInstalls = dd1.getCompositeInstallables();
				compInstalls.add(compInstall);
				dd1.setCompositeInstallables(compInstalls);
			}
			
			if (dd2.getContentUnit() instanceof ConfigurationUnit)			
			{
				compInstall = cuFactory.createCompositeInstallable(dd2.getContentUnit().getContentUnitID(), "configuration");
				Collection <ConfigurationUnit> cUs = new ArrayList <ConfigurationUnit> ();
				cUs.add((ConfigurationUnit)dd2.getContentUnit());
				compInstall.setBaseConfigurationUnits(cUs);				
				Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();
				compInstalls = dd1.getCompositeInstallables();
				compInstalls.add(compInstall);
				dd1.setCompositeInstallables(compInstalls);
			}
			
		}
		else if ((dd2.getContentUnit()==null)&&(dd1.getContentUnit()!=null))
		{
			
			SPISession session = SPISession.DEFAULT_INSTANCE;
			
			ContentUnitFactory cuFactory = session.createContentUnitFactory();
			
			CompositeInstallable compInstall = null;
			
			if (dd1.getContentUnit() instanceof InstallableUnit)
			{
				compInstall = cuFactory.createCompositeInstallable(dd1.getContentUnit().getContentUnitID(), "install");
				Collection <InstallableUnit> iUs = new ArrayList <InstallableUnit> ();
				iUs.add((InstallableUnit)dd1.getContentUnit());
				compInstall.setBaseInstallableUnits(iUs);
				Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();
				compInstalls = dd2.getCompositeInstallables();
				compInstalls.add(compInstall);
				dd2.setCompositeInstallables(compInstalls);
			}
			if (dd1.getContentUnit() instanceof LocalizationUnit)			
			{
				compInstall = cuFactory.createCompositeInstallable(dd1.getContentUnit().getContentUnitID(), "localization");
				Collection <LocalizationUnit> lUs = new ArrayList <LocalizationUnit> ();
				lUs.add((LocalizationUnit)dd1.getContentUnit());
				compInstall.setLocalizationUnits(lUs);				
				Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();
				compInstalls = dd2.getCompositeInstallables();
				compInstalls.add(compInstall);
				dd2.setCompositeInstallables(compInstalls);
			}
			
			if (dd1.getContentUnit() instanceof ConfigurationUnit)			
			{
				compInstall = cuFactory.createCompositeInstallable(dd1.getContentUnit().getContentUnitID(), "configuration");
				Collection <ConfigurationUnit> cUs = new ArrayList <ConfigurationUnit> ();
				cUs.add((ConfigurationUnit)dd1.getContentUnit());
				compInstall.setBaseConfigurationUnits(cUs);				
				Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();
				compInstalls = dd2.getCompositeInstallables();
				compInstalls.add(compInstall);
				dd2.setCompositeInstallables(compInstalls);
			}
		}		
		else if ((dd1.getContentUnit()!=null)&&(dd2.getContentUnit()!=null))
		{
			if ((dd1.getContentUnit() instanceof InstallableUnit)&&(dd2.getContentUnit() instanceof InstallableUnit))
				finaldd.setContentUnit(InstallableUnitType.merge((InstallableUnit)dd1.getContentUnit(), (InstallableUnit)dd2.getContentUnit()));
			else if ((dd1.getContentUnit() instanceof LocalizationUnit)&&(dd2.getContentUnit() instanceof LocalizationUnit))
				finaldd.setContentUnit(LocalizationUnitType.merge((LocalizationUnit)dd1.getContentUnit(), (LocalizationUnit)dd2.getContentUnit()));
			else if ((dd1.getContentUnit() instanceof ConfigurationUnit)&&(dd2.getContentUnit() instanceof ConfigurationUnit))
				finaldd.setContentUnit(ConfigurationUnitType.merge((ConfigurationUnit)dd1.getContentUnit(), (ConfigurationUnit)dd2.getContentUnit()));
			else if (dd1.getContentUnit() instanceof InstallableUnit)
			{
				SPISession session = SPISession.DEFAULT_INSTANCE;
				
				ContentUnitFactory cuFactory = session.createContentUnitFactory();
				
				CompositeInstallable compInstall = null;
				
				if (dd2.getContentUnit() instanceof LocalizationUnit)
				{
					compInstall = cuFactory.createCompositeInstallable(dd1.getContentUnit().getContentUnitID(), "installation");
					
					Collection <InstallableUnit> iUs = new ArrayList <InstallableUnit> ();
					iUs.add((InstallableUnit)dd1.getContentUnit());
					compInstall.setBaseInstallableUnits(iUs);
					
					Collection <LocalizationUnit> lUs = new ArrayList <LocalizationUnit> ();
					lUs.add((LocalizationUnit)dd2.getContentUnit());
					compInstall.setLocalizationUnits(lUs);				
									
					Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();					
					compInstalls.add(compInstall);
					
					dd1.setCompositeInstallables(compInstalls);
				}
				if (dd2.getContentUnit() instanceof ConfigurationUnit)
				{
					compInstall = cuFactory.createCompositeInstallable(dd1.getContentUnit().getContentUnitID(), "installation");
					
					Collection <InstallableUnit> iUs = new ArrayList <InstallableUnit> ();
					iUs.add((InstallableUnit)dd1.getContentUnit());
					compInstall.setBaseInstallableUnits(iUs);
					
					Collection <ConfigurationUnit> lUs = new ArrayList <ConfigurationUnit> ();
					lUs.add((ConfigurationUnit)dd2.getContentUnit());
					compInstall.setBaseConfigurationUnits(lUs);			
									
					Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();					
					compInstalls.add(compInstall);
					
					dd1.setCompositeInstallables(compInstalls);
				}
			}
			else if (dd1.getContentUnit() instanceof LocalizationUnit)
			{
				SPISession session = SPISession.DEFAULT_INSTANCE;
				
				ContentUnitFactory cuFactory = session.createContentUnitFactory();
				
				CompositeInstallable compInstall = null;
				
				if (dd2.getContentUnit() instanceof InstallableUnit)
				{
					compInstall = cuFactory.createCompositeInstallable(dd1.getContentUnit().getContentUnitID(), "installation");
					
					Collection <LocalizationUnit> iUs = new ArrayList <LocalizationUnit> ();
					iUs.add((LocalizationUnit)dd1.getContentUnit());
					compInstall.setLocalizationUnits(iUs);
					
					Collection <InstallableUnit> lUs = new ArrayList <InstallableUnit> ();
					lUs.add((InstallableUnit)dd2.getContentUnit());
					compInstall.setBaseInstallableUnits(lUs);				
									
					Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();					
					compInstalls.add(compInstall);
					
					dd1.setCompositeInstallables(compInstalls);
				}
				if (dd2.getContentUnit() instanceof ConfigurationUnit)
				{
					compInstall = cuFactory.createCompositeInstallable(dd1.getContentUnit().getContentUnitID(), "installation");
					
					Collection <LocalizationUnit> iUs = new ArrayList <LocalizationUnit> ();
					iUs.add((LocalizationUnit)dd1.getContentUnit());
					compInstall.setLocalizationUnits(iUs);
					
					Collection <ConfigurationUnit> lUs = new ArrayList <ConfigurationUnit> ();
					lUs.add((ConfigurationUnit)dd2.getContentUnit());
					compInstall.setBaseConfigurationUnits(lUs);			
									
					Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();					
					compInstalls.add(compInstall);
					
					dd1.setCompositeInstallables(compInstalls);
				}
			}
			else if (dd1.getContentUnit() instanceof ConfigurationUnit)
			{
				SPISession session = SPISession.DEFAULT_INSTANCE;
				
				ContentUnitFactory cuFactory = session.createContentUnitFactory();
				
				CompositeInstallable compInstall = null;
				
				if (dd2.getContentUnit() instanceof InstallableUnit)
				{
					compInstall = cuFactory.createCompositeInstallable(dd1.getContentUnit().getContentUnitID(), "installation");
					
					Collection <ConfigurationUnit> iUs = new ArrayList <ConfigurationUnit> ();
					iUs.add((ConfigurationUnit)dd1.getContentUnit());
					compInstall.setBaseConfigurationUnits(iUs);
					
					Collection <InstallableUnit> lUs = new ArrayList <InstallableUnit> ();
					lUs.add((InstallableUnit)dd2.getContentUnit());
					compInstall.setBaseInstallableUnits(lUs);				
									
					Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();					
					compInstalls.add(compInstall);
					
					dd1.setCompositeInstallables(compInstalls);
				}
				if (dd2.getContentUnit() instanceof LocalizationUnit)
				{
					compInstall = cuFactory.createCompositeInstallable(dd1.getContentUnit().getContentUnitID(), "installation");
					
					Collection <ConfigurationUnit> iUs = new ArrayList <ConfigurationUnit> ();
					iUs.add((ConfigurationUnit)dd1.getContentUnit());
					compInstall.setBaseConfigurationUnits(iUs);
					
					Collection <LocalizationUnit> lUs = new ArrayList <LocalizationUnit> ();
					lUs.add((LocalizationUnit)dd2.getContentUnit());
					compInstall.setLocalizationUnits(lUs);			
									
					Collection <CompositeInstallable> compInstalls = new ArrayList <CompositeInstallable> ();					
					compInstalls.add(compInstall);
					
					dd1.setCompositeInstallables(compInstalls);
				}
			}
			
		}				
		else
		{
			finaldd.setCompositeInstallables(CompositeInstallableType.merge(dd1.getCompositeInstallables(),dd2.getCompositeInstallables()));
		}
		return finaldd;
	}
	
}
