package gov.va.med.esr.common.builder.msds;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import gov.va.med.esr.common.builder.entity.ActivationMetaData;
import gov.va.med.esr.common.builder.entity.EntityBuilder;
import gov.va.med.esr.common.builder.entity.DeploymentMetaData;
import gov.va.med.esr.common.model.ee.Activation;
import gov.va.med.esr.common.model.ee.Deployment;
import gov.va.med.esr.common.model.lookup.MHDataSource;
import gov.va.med.esr.common.model.lookup.TerminationReason;
import gov.va.med.esr.common.model.lookup.SpecialOperation;
import gov.va.med.esr.common.model.lookup.NamedContingency;
import gov.va.med.fw.util.builder.Builder;
import gov.va.med.fw.util.builder.BuilderException;

/**
 * 
 * @author DNS   ruizc
 *
 */
public class ActivationBuilder extends EntityBuilder {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1661878778634701213L;
	private Builder mhDataSourceBuilder = null;
    private Builder deploymentBuilder = null;	
    private Builder terminationReasonBuilder = null;    
    private Builder specialOperationBuilder = null;
    private Builder namedContingencyBuilder = null;
	
	public Activation build(ActivationMetaData metaData) throws BuilderException {
		Activation input = metaData.getEntity();
		Activation output = (input == null) ? new Activation() : input;

		//copy data from meta data to object
		this.transfer(output, metaData);

		//verify for minimum required data
		return this.shouldKeep(output) ? output : null;
	}	

	private void transfer(Activation input, ActivationMetaData metaData) 
		throws BuilderException {

		// transfer activation data
		input.setActivationBeginDate(super.build(input.getActivationBeginDate(), 
				metaData.getActivationBeginDate()));
		input.setActivationEndDate(super.build(input.getActivationEndDate(), 
				metaData.getActivationEndDate()));
		input.setDataSource((MHDataSource)super.build(mhDataSourceBuilder, 
				input.getDataSource(), metaData.getDataSource()));
		input.setNamedContingency((NamedContingency)super.build(namedContingencyBuilder, 
				input.getNamedContingency(), metaData.getNamedContingency()));
		input.setSpecialOperation((SpecialOperation)super.build(specialOperationBuilder, 
				input.getSpecialOperation(), metaData.getSpecialOperation()));
		input.setTerminationReason((TerminationReason)super.build(terminationReasonBuilder, 
				input.getTerminationReason(), metaData.getTerminationReason()));

		// add transfer and deployment build
	   	buildDeployments(input, metaData.getDeployments());
	}

	private void buildDeployments(Activation input, 
			DeploymentMetaData[] metaData) throws BuilderException {
		Set toAdd = new HashSet();

		for (int index = 0; index < ((metaData == null) ? 0 : metaData.length); index++) {
			this.processDeployment(toAdd, metaData[index]);
		}    	
		input.removeAllDeployments();

		for (Iterator i = toAdd.iterator(); i.hasNext();) {
			input.addDeployment((Deployment) i.next());
		}    	
	}

	private void processDeployment(Set toAdd,
			DeploymentMetaData metaData) throws BuilderException {

		Deployment value = buildDeployment(null, metaData);

		if (value != null) {
			toAdd.add(value);
		}
	}    

	private Deployment buildDeployment(Deployment input, 
			DeploymentMetaData metaData) throws BuilderException {
		if (metaData == null) {
			return null;
		}

		metaData.setEntity(input);
		return (Deployment)getDeploymentBuilder().build(metaData);

	}	
	
	/**
	 * @return the deploymentBuilder
	 */
	public Builder getDeploymentBuilder() {
		return deploymentBuilder;
	}

	/**
	 * @param deploymentBuilder the deploymentBuilder to set
	 */
	public void setDeploymentBuilder(Builder deploymentBuilder) {
		this.deploymentBuilder = deploymentBuilder;
	}

	/**
	 * @return the mhDataSourceBuilder
	 */
	public Builder getMhDataSourceBuilder() {
		return mhDataSourceBuilder;
	}

	/**
	 * @param mhDataSourceBuilder the mhDataSourceBuilder to set
	 */
	public void setMhDataSourceBuilder(Builder mhDataSourceBuilder) {
		this.mhDataSourceBuilder = mhDataSourceBuilder;
	}

	/**
	 * @return the terminationReasonBuilder
	 */
	public Builder getTerminationReasonBuilder() {
		return terminationReasonBuilder;
	}

	/**
	 * @param terminationReasonBuilder the terminationReasonBuilder to set
	 */
	public void setTerminationReasonBuilder(Builder terminationReasonBuilder) {
		this.terminationReasonBuilder = terminationReasonBuilder;
	}

	/**
	 * @return the namedContingencyBuilder
	 */
	public Builder getNamedContingencyBuilder() {
		return namedContingencyBuilder;
	}

	/**
	 * @param namedContingencyBuilder the namedContingencyBuilder to set
	 */
	public void setNamedContingencyBuilder(Builder namedContingencyBuilder) {
		this.namedContingencyBuilder = namedContingencyBuilder;
	}

	/**
	 * @return the specialOperationBuilder
	 */
	public Builder getSpecialOperationBuilder() {
		return specialOperationBuilder;
	}

	/**
	 * @param specialOperationBuilder the specialOperationBuilder to set
	 */
	public void setSpecialOperationBuilder(Builder specialOperationBuilder) {
		this.specialOperationBuilder = specialOperationBuilder;
	}
	
}
