package org.eclipse.cosmos.me.sdd.tooling.btg.aggregator.comparisons;

import java.util.List;

import org.eclipse.cosmos.me.sdd.schema.ConditionType;
import org.eclipse.cosmos.me.sdd.schema.IdentityType;
import org.eclipse.cosmos.me.sdd.schema.InstallableUnitType;
import org.eclipse.cosmos.me.sdd.schema.ObjectFactory;
import org.eclipse.cosmos.me.sdd.schema.ResourceType;
import org.eclipse.cosmos.me.sdd.schema.ResultingChangeType;
import org.eclipse.cosmos.me.sdd.schema.ResultingResourceType;

public class InstallableUnitCompare {
	
	protected static InstallableUnitType merge (InstallableUnitType iu1, InstallableUnitType iu2)
	{
		if (!equals(iu1,iu2))
		{
			return null;
		}
		else
		{
			ObjectFactory objectFactory = new ObjectFactory();
			InstallableUnitType merged = objectFactory.createInstallableUnitType();
			
			merged.setId(iu1.getId());
			IdentityType i = IdentityCompare.merge(iu1.getIdentity(),iu2.getIdentity());
			if (i != null)
			{
				merged.setIdentity(i);
			}
			else return null;
			
			merged.setVariables(VariablesCompare.merge(iu1.getVariables(),iu2.getVariables()));

			ConditionType c = ConditionCompare.merge(iu1.getCondition(),iu2.getCondition());
			if (c != null)
			{
				merged.setCondition(c);
			}
			else return null;
			
			merged.setRequiredBase(RequiredBaseCompare.merge(iu1.getRequiredBase(),iu2.getRequiredBase()));
			merged.setRequirements(RequirementsCompare.merge(iu1.getRequirements(),iu2.getRequirements()));
			merged.setLanguages(LanguagesCompare.merge(iu1.getLanguages(),iu2.getLanguages()));
			merged.getCompletion().addAll(CompletionCompare.merge(iu1.getCompletion(),iu2.getCompletion()));
			//this artifacts part seems wrong but is logical as stated in the rules doc
			merged.setArtifacts(iu1.getArtifacts());
			
			return merged;
		}
	}

	private static boolean equals(InstallableUnitType unit1,
			InstallableUnitType unit2) {
		//may not have ResultingResource or ResultingChange
		//definitely need to check target though
		
		if ((unit1.getResultingResource()==null)&&(unit2.getResultingResource()!=null))
			return false;
		if ((unit1.getResultingResource()!=null)&&(unit2.getResultingResource()==null))
			return false;
		else
		{
			List<ResultingResourceType> r1 = unit1.getResultingResource();
			List<ResultingResourceType> r2 = unit2.getResultingResource();
			if (!ResultingResourceCompare.equals(r1, r2))
				return false;
		}
		
		if ((unit1.getResultingChange()==null)&&(unit2.getResultingChange()!=null))
			return false;
		if ((unit1.getResultingChange()!=null)&&(unit2.getResultingChange()==null))
			return false;
		else
		{
			List<ResultingChangeType> r1 = unit1.getResultingChange();
			List<ResultingChangeType> r2 = unit2.getResultingChange();
			if (!ResultingChangeCompare.equals(r1, r2))
				return false;
		}
		
		if (!ResourceCompare.equals((ResourceType)unit1.getTargetResourceRef(),(ResourceType)unit2.getTargetResourceRef()))
			return false;
		
		return true;
	}

}
