package gov.va.med.esr.common.rule.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import gov.va.med.esr.common.builder.entity.MilitaryServiceBuilder;
import gov.va.med.esr.common.builder.msds.MilitaryServiceBuilderForMSDS;
import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.infra.ImpreciseDateUtils;
import gov.va.med.esr.common.model.ee.CombatEpisode;
import gov.va.med.esr.common.model.ee.CombatService;
import gov.va.med.esr.common.model.ee.MilitaryServiceEpisode;
import gov.va.med.esr.common.model.ee.MilitaryServiceSiteRecord;
import gov.va.med.esr.common.model.lookup.CombatPayType;
import gov.va.med.esr.common.model.lookup.CombatServiceSource;
import gov.va.med.esr.common.model.lookup.ConflictLocation;
import gov.va.med.esr.common.model.lookup.DischargeType;
import gov.va.med.esr.common.model.lookup.MHDataSource;
import gov.va.med.esr.common.model.lookup.MsdsCountry;
import gov.va.med.esr.common.model.lookup.NamedContingency;
import gov.va.med.esr.common.model.lookup.ServiceBranch;
import gov.va.med.esr.common.model.lookup.SpecialOperation;
import gov.va.med.esr.common.model.lookup.TerminationReason;
import gov.va.med.esr.common.model.lookup.CombatPayType.Code;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.rule.data.MilitaryServiceInputData;
import gov.va.med.esr.common.rule.parameter.MilitaryServiceInputParameter;
import gov.va.med.esr.common.util.RuleAbstractTestCase;
import gov.va.med.esr.jms.vadir.outboundResponse.VadirServiceResponseWrapper;
import gov.va.med.esr.jms.vadir.outboundResponse.model.militaryHistory.Activation;
import gov.va.med.esr.jms.vadir.outboundResponse.model.militaryHistory.BIRLS;
import gov.va.med.esr.jms.vadir.outboundResponse.model.militaryHistory.Deployment;
import gov.va.med.esr.jms.vadir.outboundResponse.model.militaryHistory.MilitaryHistory;
import gov.va.med.esr.jms.vadir.outboundResponse.model.militaryHistory.MilitaryPay;
import gov.va.med.esr.jms.vadir.outboundResponse.model.militaryHistory.PeriodOfService;
import gov.va.med.esr.jms.vadir.outboundResponse.model.militaryHistory.ServicePeriod;
import gov.va.med.esr.jms.vadir.outboundResponse.model.militaryHistory.VADIR;
import gov.va.med.esr.service.MsdsResponseInfo;
import gov.va.med.esr.service.PurpleHeartService;
import gov.va.med.esr.common.model.lookup.VAFacility;

public class AbstractMsdsTest extends RuleAbstractTestCase {

	public static final String NoPersonFound = "NoPersonFound";

	public static final String MultiplePeopleFoundinBIRLS = "MultiplePeopleFoundinBIRLS";

	public static final String MultiplePeopleFoundinVADIR = "MultiplePeopleFoundinVADIR";

	public static final String ServiceNotAvaialbleBIRLS = "ServiceNotAvaialbleBIRLS";

	public static final String ServiceNotAvaialbleVADIR = "ServiceNotAvaialbleVADIR";

	public static final String AliasMatchinVADIR = "AliasMatchinVADIR";

	public static final String AliasMatchinBIRLS = "AliasMatchinBIRLS";

	public static final String NoPersonFoundinBIRLS = "NoPersonFoundInBIRLS";

	public static final String NoPersonFoundinVADIR = "NoPersonFoundInVADIR";

	public static final String NoServicePeriodsinVADIR = "NoServicePeriodsinVADIR";

	public static final String NoServicePeriodsinBIRLS = "NoServicePeriodsinBIRLS";

	public static final String Success = "Success";

	private PurpleHeartService purpleHeartService = null;

	private MilitaryServiceBuilderForMSDS militaryServiceBuilderForMSDS = null;

	private MilitaryServiceBuilder militaryServiceBuilder = null;

	public AbstractMsdsTest(String testName) {
		super(testName);
	}

	protected gov.va.med.esr.common.model.ee.Activation createEsrActivation(
			Person person) throws Exception {
		gov.va.med.esr.common.model.ee.Activation activation = new gov.va.med.esr.common.model.ee.Activation();
		activation.setNamedContingency(this.getLookupService()
				.getNamedContingencyByCode(
						NamedContingency.DISASTER_RELIEF_HURRICANE_KATRINA
								.getCode()));
		activation.setTerminationReason(this.getLookupService()
				.getTerminationReasonByCode(
						TerminationReason.COMPLETE.getCode()));
		activation.setActivationBeginDate(this.getDate(2001, 3, 2));
		activation.setActivationEndDate(this.getDate(2004, 3, 3));
		if (person.getMilitaryService() == null)
			attachMilitaryService(person);
		person.getMilitaryService().addActivation(activation);
		return activation;
	}

	protected MilitaryServiceInputParameter buildMilitaryServiceInputParameter()
			throws Exception {
		Person onfile = this.buildSimplePerson();
		MilitaryServiceSiteRecord hec = new MilitaryServiceSiteRecord();
		hec.setSite(this.getLookupService().getVaFacilityByCode(VAFacility.CODE_HEC.getCode()));
		onfile.getMilitaryService().addMilitaryServiceSiteRecord(hec);
		Person incoming = (Person) onfile.clone();
		Person pristine = (Person) onfile.clone();
		MilitaryServiceInputData ruleData = new MilitaryServiceInputData(
				incoming.getMilitaryService(), onfile, pristine, true);
		MilitaryServiceInputParameter militaryServiceInput = new MilitaryServiceInputParameter();
		militaryServiceInput.setApplicationContext(this.applicationContext);
		militaryServiceInput.setLookupService(this.getLookupService());
		militaryServiceInput.setTimestampManagerName("common.timestampManager");
		militaryServiceInput.setMergeRuleService(this.getMergeRuleService());
		militaryServiceInput.setRuleDataAware(ruleData);
		return militaryServiceInput;
	}

	protected CombatService createCombatService(Person person) throws Exception {
		CombatService cs = new CombatService();
		ImpreciseDate start = new ImpreciseDate("200112");
		ImpreciseDate end = new ImpreciseDate("200312");
		cs.setCombatPayType(this.getLookupService().getCombatPayTypeByCode(
				CombatPayType.CODE_COMBAT_ZONE_TAX_EXCLUSION));
		cs.setCombatServiceSource(this.getLookupService()
				.getCombatServiceSourceByCode(
						CombatServiceSource.CODE_WEBHINQ.getCode()));

		cs.setPayStartDate(start);
		cs.setPayEndDate(end);
		if (person.getMilitaryService() == null)
			this.attachMilitaryService(person);
		person.getMilitaryService().addCombatService(cs);
		return cs;
	}

	protected CombatEpisode createCombatEpisode() throws Exception {
		CombatEpisode ce = new CombatEpisode();
		ce.setConflictLocation(this.getLookupService().getConflictByCode(
				ConflictLocation.CODE_OEF.getCode()));
		ce.setStartDate(ImpreciseDateUtils.createImpreciseDate(2002, 2, 1));
		ce.setEndDate(ImpreciseDateUtils.createImpreciseDate(2008, 11, 1));
		return ce;
	}

	protected gov.va.med.esr.common.model.ee.Deployment createEsrDeployment()
			throws Exception {
		gov.va.med.esr.common.model.ee.Deployment deployment = new gov.va.med.esr.common.model.ee.Deployment();
		deployment.setSpecialOperation(this.getLookupService()
				.getSpecialOperationByCode(
						SpecialOperation.OPERATION_ENDURING_FREEDOM.getCode()));
		deployment.setTerminationReason(this.getLookupService()
				.getTerminationReasonByCode(
						TerminationReason.COMPLETE.getCode()));
		deployment.setDataSource(this.getLookupService().getMHDataSourceByCode(
				MHDataSource.VADIR.getCode()));
		Date beginDate = ImpreciseDateUtils
				.getDateWithDefault(ImpreciseDateUtils.createImpreciseDate(
						2001, 1, 1));
		Date endDate = ImpreciseDateUtils.getDateWithDefault(ImpreciseDateUtils
				.createImpreciseDate(2005, 1, 1));
		deployment.setDeploymentBeginDate(beginDate);
		deployment.setDeploymentEndDate(endDate);
		deployment.setCountry(this.getLookupService().getMsdsCountryByCode(
				MsdsCountry.CODE_USA.getCode()));

		return deployment;
	}

	// GOAL
	protected PeriodOfService createBirlsPeriodOfService(String branch,
			String charOfService, Date start, Date end) {
		PeriodOfService periodOfService = new PeriodOfService();
		periodOfService.setBranchOfService(branch);
		periodOfService.setCharacterOfService(charOfService);
		periodOfService.setReleasedActiveDutyDate(end);
		periodOfService.setEnteredOnDutyDate(start);
		return periodOfService;
	}
	protected MilitaryServiceEpisode createMilitaryServiceEpisode(Date start, Date end) throws Exception {
		ServiceBranch branch = getLookupService().getServiceBranchByCode(ServiceBranch.CODE_AIR_FORCE.getCode());
		return this.createMilitaryServiceEpisode(branch, ImpreciseDateUtils.createImpreciseDateWithoutTime(start), 
				ImpreciseDateUtils.createImpreciseDateWithoutTime(end));
	}
	protected MilitaryServiceEpisode createMilitaryServiceEpisode(
			ServiceBranch branch, ImpreciseDate start, ImpreciseDate end)
			throws Exception {
		MilitaryServiceEpisode mse = new MilitaryServiceEpisode();
		mse.setServiceBranch(branch == null ? this.getRandomServiceBranch()
				: branch);
		mse.setDischargeType(this.getLookupService().getDischargeTypeByCode(
				DischargeType.CODE_HONORABLE.getCode()));
		mse.setStartDate(start);
		mse.setEndDate(end);
		mse.setServiceNumber("12345");
		return mse;
	}

	// TODO - cleanup
	protected VadirServiceResponseWrapper createWrapper(long val,
			PeriodOfService birlsPeriodOfService,
			ServicePeriod vadirServicePeriod, int newParam) throws Exception {
		MilitaryServiceBuilderForMSDS msdsBuilder = this
				.getMilitaryServiceBuilderForMSDS();
		VadirServiceResponseWrapper wrapper = new VadirServiceResponseWrapper();
		wrapper.setPersonId(new Long(val).longValue());
		if (newParam == 2) {
			wrapper.setErrorMessage(NoPersonFound);
			return wrapper;

		}
		if (newParam == 3) {
			wrapper.setErrorMessage(null);
			return wrapper;

		}

		MilitaryHistory mockMilitaryHistory = new MilitaryHistory();
		BIRLS birls = new BIRLS();
		VADIR vadir = new VADIR();
		PeriodOfService periodOfService = new PeriodOfService();
		ServicePeriod servicePeriod = new ServicePeriod();
		Activation activationV = new Activation();
		Activation activationX = new Activation();
		Deployment deploymentV = new Deployment();
		Deployment deploymentX = new Deployment();

		if (birlsPeriodOfService != null) {
			periodOfService = birlsPeriodOfService;
		} else {
			// BIRLS
			periodOfService.setBranchOfService("WAC");
			periodOfService.setCharacterOfService("HON");
			// periodOfService.setCharacterOfService(" ");
			periodOfService.setReleasedActiveDutyDate(this.getDate(2009, 1, 8));
			periodOfService.setEnteredOnDutyDate(this.getDate(2003, 1, 8));
			periodOfService.setBranchOfService("WAC");
		}

		if (vadirServicePeriod != null) {
			servicePeriod = vadirServicePeriod;
		} else {
			// Military Service Episodes
			servicePeriod.setStartDate(this.getDate(2008, 1, 8));
			servicePeriod.setEndDate(this.getDate(2010, 1, 8));
			servicePeriod.setBranchOfService("A");
			servicePeriod.setPersonnelCategory("A");
			servicePeriod.setCharacterOfService("A");
		}

		ServicePeriod servicePeriod2 = new ServicePeriod();
		if (newParam == 1) {
			// Military Service Episodes
			servicePeriod2.setStartDate(this.getDate(2000, 1, 8));
			servicePeriod2.setEndDate(this.getDate(2001, 1, 8));
			servicePeriod2.setBranchOfService("WAC");
			servicePeriod2.setPersonnelCategory("A");
			servicePeriod2.setCharacterOfService("A");

			periodOfService.setEnteredOnDutyDate(this.getDate(2006, 1, 8));
			periodOfService.setReleasedActiveDutyDate(this.getDate(2007, 1, 8));
			periodOfService.setCharacterOfService(null);

			servicePeriod.setStartDate(this.getDate(2005, 1, 8));
			servicePeriod.setEndDate(this.getDate(2006, 1, 8));
			servicePeriod.setCharacterOfService(null);
		}
		vadir.setOefOifIndicator("02"); // OEF

		// BIRLS
		List periodOfServices = new ArrayList();
		periodOfServices.add(periodOfService);
		birls.setPeriodOfService(periodOfServices);
		birls.setMedalOfHonorInd("Y");
		birls.setPurpleHeartInd("Y");
		mockMilitaryHistory.setBirls(birls);

		// VADIR
		activationV.setStartDate(this.getDate(2002, 1, 8));
		activationV.setEndDate(this.getDate(2005, 1, 8));
		activationV.setTerminationRsn("D");
		activationX.setStartDate(this.getDate(2006, 1, 8));
		activationX.setEndDate(this.getDate(2007, 1, 8));
		activationX.setTerminationRsn("D");

		deploymentV.setStartDate(this.getDate(2002, 1, 8));
		deploymentV.setEndDate(this.getDate(2003, 1, 8));
		deploymentV.setTerminationRsn("D");
		deploymentV.setSpecialOperation("14");

		deploymentX.setStartDate(this.getDate(2003, 2, 8));
		deploymentX.setEndDate(this.getDate(2005, 6, 8));
		deploymentX.setTerminationRsn("D");
		deploymentX.setSpecialOperation("14");

		// Deployments
		List deploymentsV = new ArrayList();
		deploymentsV.add(deploymentV);
		deploymentsV.add(deploymentX);
		servicePeriod.setDeployments(deploymentsV);

		// Activations
		List activationsV = new ArrayList();
		activationsV.add(activationV);
		activationsV.add(activationX);
		servicePeriod.setActivations(activationsV);

		// Combat Service
		MilitaryPay payV = new MilitaryPay();
		payV.setPayType("01");
		payV.setStartDate(this.getDate(2004, 1, 8));
		payV.setEndDate(this.getDate(2005, 1, 8));

		List pays = new ArrayList();
		pays.add(payV);
		servicePeriod.setMilitaryPayments(pays);

		List servicePeriodsV = new ArrayList();
		servicePeriodsV.add(servicePeriod);
		if (newParam > 0) {
			servicePeriodsV.add(servicePeriod2);
		}
		vadir.setServicePeriods(servicePeriodsV);

		mockMilitaryHistory.setVadir(vadir);
		wrapper.setResult(mockMilitaryHistory);
		// /////////////////////////////////////////////
		// Do a build
		// /////////////////////////////////////////////

		return wrapper;
	}

	protected MsdsResponseInfo createMockMsdsResponseInfo(long val,
			PeriodOfService birlsPeriodOfService,
			ServicePeriod vadirServicePeriod, int newParam) throws Exception {
		MilitaryServiceBuilderForMSDS msdsBuilder = this
				.getMilitaryServiceBuilderForMSDS();

		VadirServiceResponseWrapper wrapper = this.createWrapper(val,
				birlsPeriodOfService, vadirServicePeriod, newParam);
		return (MsdsResponseInfo) msdsBuilder.build(wrapper);
	}

	// TODO - cleanup	
	protected MsdsResponseInfo createMockMsdsResponseInfoFromOneSource(
			long val, PeriodOfService birlsPeriodOfService,
			ServicePeriod vadirServicePeriod, int newParam) throws Exception {
		MilitaryServiceBuilderForMSDS msdsBuilder = this
				.getMilitaryServiceBuilderForMSDS();
		VadirServiceResponseWrapper wrapper = new VadirServiceResponseWrapper();
		wrapper.setPersonId(new Long(val).longValue());

		MilitaryHistory mockMilitaryHistory = new MilitaryHistory();
		BIRLS birls = new BIRLS();

		PeriodOfService periodOfService = new PeriodOfService();

		if (birlsPeriodOfService != null) {
			periodOfService = birlsPeriodOfService;
		} else {
			// BIRLS
			periodOfService.setCharacterOfService("HON");
			// periodOfService.setCharacterOfService(" ");
			periodOfService.setReleasedActiveDutyDate(this.getDate(2003, 1, 8));
			periodOfService.setEnteredOnDutyDate(this.getDate(2003, 1, 8));
			periodOfService.setBranchOfService("NAVY");
		}

		// BIRLS
		List periodOfServices = new ArrayList();
		periodOfServices.add(periodOfService);
		birls.setPeriodOfService(periodOfServices);
		birls.setMedalOfHonorInd("Y");
		birls.setPurpleHeartInd("Y");
		mockMilitaryHistory.setBirls(birls);

		mockMilitaryHistory.setReturnStatus(this.NoPersonFoundinVADIR);
		wrapper.setResult(mockMilitaryHistory);

		// /////////////////////////////////////////////
		// Do a build
		// /////////////////////////////////////////////

		return (MsdsResponseInfo) msdsBuilder.build(wrapper);
	}

	protected Activation createVadirActivation(Date start, Date end,
			String termReason) {
		Activation activation = new Activation();
		activation.setStartDate(start);
		activation.setEndDate(end);
		activation.setTerminationRsn(termReason);
		return activation;
	}

	// GOAL
	protected MilitaryPay createVadirMilitaryPay(String location, Date start,
			Date end, Code payType) throws Exception {
		MilitaryPay pay = new MilitaryPay();
		pay.setCombatServiceLocation(location);
		pay.setStartDate(start);
		pay.setEndDate(end);
		pay.setPayType(payType.getCode());
		return pay;
	}

	// GOAL
	protected ServicePeriod createVadirServicePeriod(String branch,
			String charOfService, String personnelCategory, Date start, Date end) {
		ServicePeriod servicePeriod = new ServicePeriod();
		servicePeriod.setBranchOfService(branch);
		servicePeriod.setCharacterOfService(charOfService);
		servicePeriod.setPersonnelCategory(personnelCategory);
		servicePeriod.setStartDate(start);
		servicePeriod.setEndDate(end);
		return servicePeriod;
	}

	protected Deployment createVadirDeployment(Date start, Date end,
			String termReason, String specialOp, String location) {
		Deployment deployment = new Deployment();
		deployment.setStartDate(start);
		deployment.setEndDate(end);
		deployment.setTerminationRsn(termReason);
		deployment.setSpecialOperation(specialOp);
		deployment.setLocation(location);
		return deployment;
	}

	/**
	 * @return the purpleHeartService
	 */
	public PurpleHeartService getPurpleHeartService() {
		return purpleHeartService;
	}

	/**
	 * @param purpleHeartService
	 *            the purpleHeartService to set
	 */
	public void setPurpleHeartService(PurpleHeartService purpleHeartService) {
		this.purpleHeartService = purpleHeartService;
	}

	/**
	 * @return the militaryServiceBuilder
	 */
	public MilitaryServiceBuilder getMilitaryServiceBuilder() {
		return militaryServiceBuilder;
	}

	/**
	 * @param militaryServiceBuilder
	 *            the militaryServiceBuilder to set
	 */
	public void setMilitaryServiceBuilder(
			MilitaryServiceBuilder militaryServiceBuilder) {
		this.militaryServiceBuilder = militaryServiceBuilder;
	}

	/**
	 * @return the militaryServiceBuilderForMSDS
	 */
	public MilitaryServiceBuilderForMSDS getMilitaryServiceBuilderForMSDS() {
		return militaryServiceBuilderForMSDS;
	}

	/**
	 * @param militaryServiceBuilderForMSDS
	 *            the militaryServiceBuilderForMSDS to set
	 */
	public void setMilitaryServiceBuilderForMSDS(
			MilitaryServiceBuilderForMSDS militaryServiceBuilderForMSDS) {
		this.militaryServiceBuilderForMSDS = militaryServiceBuilderForMSDS;
	}

}