package gov.va.med.esr.jms.vadir;

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 java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.datatype.XMLGregorianCalendar;

import org.springframework.stereotype.Service;

@Service
public class StubTranslationService {

	public MilitaryHistory translate(
			gov.va.schema.militaryhistory.MilitaryHistory mh) {
		if (mh == null) return null;
		
		MilitaryHistory result = new MilitaryHistory();
		result.setBirls(translate(mh.getBIRLS()));
		result.setIcn(mh.getICN());
		result.setQueryId(mh.getQueryId());
		result.setReturnStatus(mh.getReturnStatus());
		result.setVadir(translate(mh.getVADIR()));
		return result;
	}

	private VADIR translate(gov.va.schema.militaryhistory.VADIR vadir) {
		if (vadir == null) return null;
		
		VADIR result = new VADIR();
		result.setOefOifIndicator(vadir.getOefOifIndicator());
		result.setRetirementStatusIndicator(vadir
				.getRetirementStatusIndicator());
		result.setServicePeriods(convertList(vadir.getServicePeriods(),
				new ServicePeriodTranslator()));
		result.setVaId(vadir.getVaId());
		result.setDeathDate(convertCal(vadir.getDeathDate()));
		result.setDeathIndicator(vadir.getDeathIndicator());
		return result;
	}

	private BIRLS translate(gov.va.schema.militaryhistory.BIRLS birls) {
		if (birls == null) return null;
		
		BIRLS result = new BIRLS();
		result.setDisabilityInd(birls.getDisabilityInd());
		result.setMedalOfHonorInd(birls.getMedalOfHonorInd());
		result.setPeriodOfService(convertList(birls.getPeriodOfService(),
				new PeriodOfServiceTranslator()));
		result.setPurpleHeartInd(birls.getPurpleHeartInd());
		result.setRecurServiceNumber(birls.getRecurServiceNumber());
		result.setVadsInd(birls.getVADSInd());
		result.setVerifiedSvcDataInd(birls.getVerifiedSvcDataInd());
		return result;
	}

	private class PeriodOfServiceTranslator
			implements
			ItemTranslator<gov.va.schema.militaryhistory.PeriodOfService, PeriodOfService> {
		@Override
		public PeriodOfService translate(
				gov.va.schema.militaryhistory.PeriodOfService source) {
			if (source == null) return null;
			
			PeriodOfService result = new PeriodOfService();
			result.setBranchOfService(source.getBranchOfService());
			result.setCharacterOfService(source.getCharacterOfService());
			result.setEnteredOnDutyDate(convertCal(source
					.getEnteredOnDutyDate()));
			result.setReleasedActiveDutyDate(convertCal(source
					.getReleasedActiveDutyDate()));
			result.setSeparationReason(source.getSeparationReason());
			return result;
		}
	}

	private class ServicePeriodTranslator
			implements
			ItemTranslator<gov.va.schema.militaryhistory.ServicePeriod, ServicePeriod> {
		@Override
		public ServicePeriod translate(
				gov.va.schema.militaryhistory.ServicePeriod source) {
			if (source == null) return null;
			
			ServicePeriod result = new ServicePeriod();

			result.setActivations(convertList(source.getActivations(),
					new ActivationTranslator()));
			result.setBranchOfService(source.getBranchOfService());
			result.setCharacterOfService(source.getCharacterOfService());
			result.setDeployments(convertList(source.getDeployments(),
					new DeploymentTranslator()));
			result.setEndDate(convertCal(source.getEndDate()));
			result.setMilitaryPayments(convertList(
					source.getMilitaryPayments(), new MilitaryPayTranslator()));
			result.setPersonnelCategory(source.getPersonnelCategory());
			result.setStartDate(convertCal(source.getStartDate()));
			return result;
		}

	}

	private class ActivationTranslator
			implements
			ItemTranslator<gov.va.schema.militaryhistory.Activation, Activation> {
		@Override
		public Activation translate(
				gov.va.schema.militaryhistory.Activation source) {
			if (source == null) return null;
			
			Activation result = new Activation();
			result.setCharacterOfService(source.getCharacterOfService());
			result.setEndDate(convertCal(source.getEndDate()));
			result.setStartDate(convertCal(source.getStartDate()));
			result.setTerminationRsn(source.getTerminationRsn());
			return result;
		}
	}

	private class DeploymentTranslator
			implements
			ItemTranslator<gov.va.schema.militaryhistory.Deployment, Deployment> {
		@Override
		public Deployment translate(
				gov.va.schema.militaryhistory.Deployment source) {
			if (source == null) return null;
			
			Deployment result = new Deployment();
			result.setEndDate(convertCal(source.getEndDate()));
			result.setLocation(source.getLocation());
			result.setSpecialOperation(source.getSpecialOperation());
			result.setStartDate(convertCal(source.getStartDate()));
			result.setTerminationRsn(source.getTerminationRsn());
			return result;
		}
	}

	private class MilitaryPayTranslator
			implements
			ItemTranslator<gov.va.schema.militaryhistory.MilitaryPay, MilitaryPay> {
		@Override
		public MilitaryPay translate(
				gov.va.schema.militaryhistory.MilitaryPay source) {
			if (source == null) return null;
			
			MilitaryPay result = new MilitaryPay();
			result.setCombatServiceLocation(String.valueOf(source
					.getCombatServiceLocation()));
			result.setEndDate(convertCal(source.getEndDate()));
			result.setPayType(source.getPayType());
			result.setStartDate(convertCal(source.getStartDate()));
			return result;
		}
	}

	private Date convertCal(XMLGregorianCalendar endDate) {
		return endDate == null ? null : endDate.toGregorianCalendar().getTime();
	}

	private <T, U> List<U> convertList(List<T> source,
			ItemTranslator<T, U> translator) {
		if (source == null) return null;
		
		List<U> result = new ArrayList<U>();
		for (T item : source)
			result.add(translator.translate(item));
		return result;
	}

	interface ItemTranslator<T, U> {
		U translate(T source);
	}

}
