/**
 *
 */
package gov.va.med.esr.voa.webservice.builder.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.financials.Asset;
import gov.va.med.esr.common.model.financials.DependentFinancials;
import gov.va.med.esr.common.model.financials.Expense;
import gov.va.med.esr.common.model.financials.FinancialStatement;
import gov.va.med.esr.common.model.financials.Income;
import gov.va.med.esr.common.model.financials.IncomeTest;
import gov.va.med.esr.common.model.financials.SpouseFinancials;
import gov.va.med.esr.common.model.lookup.ExpenseType;
import gov.va.med.esr.common.model.lookup.Gender;
import gov.va.med.esr.common.model.lookup.IncomeTestSource;
import gov.va.med.esr.common.model.lookup.IncomeType;
import gov.va.med.esr.common.model.lookup.PhoneType;
import gov.va.med.esr.common.model.lookup.Relationship;
import gov.va.med.esr.common.model.lookup.SSNType;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.party.Address;
import gov.va.med.esr.common.model.party.Phone;
import gov.va.med.esr.common.model.person.Dependent;
import gov.va.med.esr.common.model.person.Name;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.SSN;
import gov.va.med.esr.common.model.person.Spouse;
import gov.va.med.esr.voa.webservice.AddressInfo;
import gov.va.med.esr.voa.webservice.AssetInfo;
import gov.va.med.esr.voa.webservice.DependentFinancialsInfo;
import gov.va.med.esr.voa.webservice.DependentInfo;
import gov.va.med.esr.voa.webservice.ExpenseInfo;
import gov.va.med.esr.voa.webservice.FinancialStatementInfo;
import gov.va.med.esr.voa.webservice.FinancialsInfo;
import gov.va.med.esr.voa.webservice.IncomeInfo;
import gov.va.med.esr.voa.webservice.IncomeTestInfo;
import gov.va.med.esr.voa.webservice.SpouseFinancialsInfo;
import gov.va.med.esr.voa.webservice.SpouseInfo;
import gov.va.med.esr.voa.webservice.SsnInfo;
import gov.va.med.esr.voa.webservice.SubmitFormRequest;
import gov.va.med.esr.voa.webservice.builder.FinancialsBuilderFactory;
import gov.va.med.fw.service.AbstractComponent;
import gov.va.med.fw.util.StringUtils;
import gov.va.med.esr.service.VOAApplicationService;


/**
 * @author DNS   CHINNR
 *
 */
public class FinancialsBuilderFactoryImpl extends AbstractComponent implements FinancialsBuilderFactory  {

	private TypesHelper typesHelper = new TypesHelper();
	private BuildHelper buildHelper = new BuildHelper();


	/**
	 * RTC Task 236652  - When a veteran answers no to the disclose financial details option the VOA form, ES/VOA
	 * backend sets some default fields to the IncomeTest so that Means Test does not go into the Pending status.
	 * included VOAApplicationService in the method signature
	 * @throws Exception
	 */
	public void buildFinancialServices(Person person, SubmitFormRequest submitFormRequest, VOAApplicationService voaApplicationService) throws Exception{
		buildFinancials(person,submitFormRequest, voaApplicationService);

	}

	/**
	 * * RTC Task 236652  - When a veteran answers no to the disclose financial details option the VOA form, ES/VOA
	 * backend sets some default fields to the IncomeTest so that Means Test does not go into the Pending status.
	 * Added a case to handle the scenario for no incomeTest passed by VOA.
	 * @throws Exception
	 */
	public void buildFinancials(Person person, SubmitFormRequest submitFormRequest, VOAApplicationService voaApplicationService) throws Exception {
		if (person != null){
			getIncomeTestInfo(person, submitFormRequest, voaApplicationService);
			//Prepare the financial statement for the current income year.
			getFinancialStatement(person, submitFormRequest);
		}
	}

	private  void getIncomeTestInfo(Person person, SubmitFormRequest submitFormRequest, VOAApplicationService voaApplicationService){

		IncomeTest currIncomeTest = new IncomeTest();


		/**
		 * RTC Task 236652  - veteran selects No for the disclose financial details from the VOA UI
		 * FinancialStatement tag comes as null and so no incomeTest
		 */

		FinancialsInfo financialsInfo = submitFormRequest.getForm().getSummary().getFinancialsInfo();

		if (financialsInfo == null || financialsInfo.getIncomeTest() == null ||
				Boolean.FALSE.equals(financialsInfo.getIncomeTest().isDiscloseFinancialInformation())){


			currIncomeTest.setDiscloseFinancialInformation(Boolean.FALSE);
			currIncomeTest.setAgreesToPayDeductible(Boolean.TRUE);
			currIncomeTest.setSendForAdjudication(Boolean.FALSE);

			//Set HEC as Source of financial info
			currIncomeTest.setSource(typesHelper.getIncomeTestSource(IncomeTestSource.CODE_HEC.getCode()));

			//sets today's date as the completed and effective dates
			Date rightNow = Calendar.getInstance().getTime();

			currIncomeTest.setEffectiveDate(rightNow);

			currIncomeTest.setIncomeYear(typesHelper.getIncomeYear());
			person.setIncomeTest(typesHelper.getIncomeYear(), currIncomeTest);

		}
		else if (submitFormRequest.getForm().getSummary().getFinancialsInfo().getIncomeTest() != null) {

			IncomeTestInfo  incomeTestInfo = submitFormRequest.getForm().getSummary().getFinancialsInfo().getIncomeTest();

			if(incomeTestInfo != null) {

				//RTC 236652 - setting defaults
				currIncomeTest.setDiscloseFinancialInformation(Boolean.TRUE);
				currIncomeTest.setAgreesToPayDeductible(Boolean.TRUE);
				currIncomeTest.setSendForAdjudication(Boolean.FALSE);
				currIncomeTest.setEffectiveDate(new Date());


				if(incomeTestInfo.getTotalIncome() != null){
					currIncomeTest.setTotalIncome(incomeTestInfo.getTotalIncome());
				}

				if(incomeTestInfo.getNetIncome() != null) {
					currIncomeTest.setNetIncome(incomeTestInfo.getNetIncome());
				}

				if (incomeTestInfo.getIncomeYear() != null) {
					currIncomeTest.setIncomeYear(incomeTestInfo.getIncomeYear());
					person.setIncomeTest(incomeTestInfo.getIncomeYear(), currIncomeTest);
				} else {
					currIncomeTest.setIncomeYear(typesHelper.getIncomeYear());
					person.setIncomeTest(typesHelper.getIncomeYear(), currIncomeTest);
				}
			}

		}
	}

	@SuppressWarnings("rawtypes")
	private  void getFinancialStatement(Person person, SubmitFormRequest submitFormRequest) throws Exception {

		if(submitFormRequest.getForm().getSummary().getFinancialsInfo() != null &&
					submitFormRequest.getForm().getSummary().getFinancialsInfo().getFinancialStatement()!= null){

				FinancialStatementInfo fStatementInfo = submitFormRequest.getForm().getSummary().getFinancialsInfo().getFinancialStatement();
				FinancialStatement statement = new FinancialStatement();

				if (fStatementInfo != null) {

					if(fStatementInfo.isMarriedLastCalendarYear() != null)
						statement.setMarriedLastCalendarYear(fStatementInfo.isMarriedLastCalendarYear());


					if(fStatementInfo.getNumberOfDependentChildren() != null)
						statement.setNumberOfDependentChildren(fStatementInfo
							.getNumberOfDependentChildren());

					if(fStatementInfo.getSpouseFinancialsList() != null && fStatementInfo.getSpouseFinancialsList().getSpouseFinancials() != null &&
							fStatementInfo.getSpouseFinancialsList().getSpouseFinancials().get(0) != null
							&& fStatementInfo.getSpouseFinancialsList().getSpouseFinancials().get(0).isContributedToSpousalSupport() != null) {
						statement.setContributedToSpouseInd( fStatementInfo.getSpouseFinancialsList().getSpouseFinancials().get(0).isContributedToSpousalSupport());
					}


					getDependentFinInfo(statement, fStatementInfo);

					//income
					if(fStatementInfo.getIncomes() != null &&
							fStatementInfo.getIncomes().getIncome() != null){
					List<IncomeInfo> incomeList = fStatementInfo.getIncomes().getIncome();
					if (incomeList != null) {
						Iterator incomeIter = incomeList.iterator();
						while (incomeIter.hasNext()) {
							IncomeInfo incomeinfo = (IncomeInfo) incomeIter.next();
							if (incomeinfo != null && incomeinfo.getType() != null) {
								Income income = buildHelper.buildIncomeInfo(incomeinfo);
								statement.addIncome(this.typesHelper.getIncomeType(incomeinfo.getType()), income);
							}
						}
					}
				} else {
					person.getIncomeTest(typesHelper.getIncomeYear()).setDiscloseFinancialInformation(Boolean.FALSE);

				}

					//asset
				if(fStatementInfo.getAssets() != null &&
						fStatementInfo.getAssets().getAsset() != null){
					List<AssetInfo> assetList = fStatementInfo.getAssets().getAsset();

					if (assetList != null) {
						Iterator assetIter = assetList.iterator();
						while (assetIter.hasNext()) {
							AssetInfo assetInfo = (AssetInfo)assetIter.next();
							if(assetInfo != null && assetInfo.getAssetType() != null){
								Asset asset = buildHelper.buildAssetInfo(assetInfo);
								statement.addAsset(this.typesHelper.getAssetType(assetInfo.getAssetType()), asset);
								}
						}
					}
				}

					//expense
			 if(fStatementInfo.getExpenses() != null &&
					 fStatementInfo.getExpenses().getExpense() != null){
					List<ExpenseInfo> expenseList = fStatementInfo.getExpenses().getExpense();
					if (expenseList != null) {
						Iterator expenseIter = expenseList.iterator();

						while (expenseIter.hasNext()) {
							ExpenseInfo expenseInfo = (ExpenseInfo) expenseIter.next();
							if (expenseInfo != null) {
								Expense expense = buildHelper.buildExpenseInfo(expenseInfo);
								ExpenseType expenseType = this.typesHelper.getExpenseType(expenseInfo.getExpenseType());


								//statement.addExpense(this.typesHelper.getExpenseType(expenseInfo.getExpenseType()), expense);
								statement.addExpense(expenseType, expense);

								if (expenseType.getCode().equals(ExpenseType.EXPENSE_TYPE_NON_REIMBURSED_MEDICAL.getCode())) {
									Expense newExpense = buildHelper.buildExpenseInfo(expenseInfo);
									statement.addExpense(this.typesHelper.getExpenseType(ExpenseType.EXPENSE_TYPE_ADJUSTED_MEDICAL.getCode()), newExpense);
								}
							}
						}
					}
			 }

			 //VOA UI does not send any income Year, so need to default to the current Income Year
			 Integer incomeYear = null;
			 if (fStatementInfo.getIncomeYear() == null){
				 incomeYear = typesHelper.getIncomeYear();
			 }
			 else {
				 incomeYear = fStatementInfo.getIncomeYear();
			 }

			 //calculate spouse financials
			 statement.setIncomeYear(incomeYear);

			 getSpouseFinInfo(statement,fStatementInfo, submitFormRequest);

			 //add spouse phone as formatted value in the right place, it doesn't get picked up from build spouse from address.getphonenumber()
			 if (statement != null && statement.getSpouseFinancials() != null && statement.getSpouseFinancials().iterator().hasNext() && statement.getSpouseFinancials().iterator().next() != null) {
				 SpouseFinancials spf = (SpouseFinancials)statement.getSpouseFinancials().iterator().next();
				 if (spf.getReportedOn() != null && spf.getReportedOn().getAddress() != null && spf.getReportedOn().getAddress().getPhoneNumber() != null) {

					 try {
						   Phone ph =  new Phone();

				           ph.setChangeDate(new Date());
				           ph.setSiteOfChange(typesHelper.getLookupService().getVaFacilityByStationNumber(VAFacility.CODE_HEC.getCode()));
				           ph.setType(typesHelper.getLookupService().getPhoneTypeByCode(PhoneType.CODE_HOME.getCode()));
				           String num = String.format("(%s) %s-%s", spf.getReportedOn().getAddress().getPhoneNumber().substring(0, 3), spf.getReportedOn().getAddress().getPhoneNumber().substring(3, 6),
				        		   spf.getReportedOn().getAddress().getPhoneNumber().substring(6, 10));
				           ph.setPhoneNumber(num);
				           spf.getReportedOn().setHomePhone(ph);
					 } catch (Exception ex) {
						 logger.error("Unknown error setting spouse phone number", ex);
						 throw new Exception (ex);
					 }
				 }
			 }

			}

			if (fStatementInfo.getIncomeYear() != null){
				person.setFinancialStatement(fStatementInfo.getIncomeYear(), statement);
			} else{
				person.setFinancialStatement(typesHelper.getIncomeYear(), statement);
			}
		}
		else {
			//RTC 236652- default blank statement added when non-disclosure = Yes
			FinancialStatement statement = new FinancialStatement();
			statement.setIncomeYear(typesHelper.getIncomeYear());
			person.setFinancialStatement(typesHelper.getIncomeYear(), statement);

		}
	}

	@SuppressWarnings("rawtypes")
	private  void getDependentFinInfo(FinancialStatement statement, FinancialStatementInfo fStatementInfo) throws Exception {

	 if(fStatementInfo.getDependentFinancialsList() != null &&
				fStatementInfo.getDependentFinancialsList().getDependentFinancials() != null){
		List<DependentFinancialsInfo> dependentFinanList = fStatementInfo.getDependentFinancialsList().getDependentFinancials();

		Iterator itr = dependentFinanList != null ? dependentFinanList.iterator()
				: null;

		while (itr != null && itr.hasNext()) {
			DependentFinancialsInfo dependentFinInfo = (DependentFinancialsInfo) itr
					.next();
			DependentFinancials dependentFinancials = new DependentFinancials();

			if (dependentFinInfo != null && dependentFinInfo.getDependentInfo() != null)
			{
				dependentFinancials.setReportedOn(buildDependent(dependentFinInfo.getDependentInfo()));

			}

			if(dependentFinInfo.isAttendedSchool() != null)dependentFinancials.setAttendedSchool(dependentFinInfo.isAttendedSchool());

			if(dependentFinInfo.isHasIncome() != null)dependentFinancials.setHasIncome(dependentFinInfo.isHasIncome());
			//CCR13373: existing code has the indicator and setting it already
			if(dependentFinInfo.isContributedToSupport() != null)dependentFinancials.setContributedToSupport(dependentFinInfo.isContributedToSupport());

			if(dependentFinInfo.isIncapableOfSelfSupport() != null)dependentFinancials.setIncapableOfSelfSupport(dependentFinInfo.isIncapableOfSelfSupport());

			if(dependentFinInfo.isIncomeAvailableToPatient() != null)dependentFinancials.setIncomeAvailableToPatient(dependentFinInfo.isIncomeAvailableToPatient());


			boolean hasEmploymentIncome = false;
			//income
			if(dependentFinInfo.getIncomes() != null &&
					dependentFinInfo.getIncomes().getIncome() != null) {
				List<IncomeInfo> incomeList = dependentFinInfo.getIncomes().getIncome();
				if (incomeList != null) {
					Iterator incomeIter = incomeList.iterator();
					while (incomeIter.hasNext()) {
						IncomeInfo incomeinfo = (IncomeInfo) incomeIter.next();
						if (incomeinfo != null && incomeinfo.getType() != null) {
							Income income = buildHelper.buildIncomeInfo(incomeinfo);

							dependentFinancials.addIncome(this.typesHelper.getIncomeType(incomeinfo.getType()), income);
							if (incomeinfo.getType() != null && incomeinfo.getType().equalsIgnoreCase("7")) {
								if (incomeinfo.getAmount() != null && incomeinfo.getAmount().intValue() >= 1) {
									hasEmploymentIncome = true;
								}
							}
						}
					}
				}
			}

			if(dependentFinInfo.getAssets() != null &&
					dependentFinInfo.getAssets().getAsset() != null){
				List<AssetInfo> assetList = dependentFinInfo.getAssets().getAsset();

				if (assetList != null) {
					Iterator assetIter = assetList.iterator();
					while (assetIter.hasNext()) {
						AssetInfo assetInfo = (AssetInfo)assetIter.next();
						if(assetInfo != null && assetInfo.getAssetType() != null){
							Asset asset = buildHelper.buildAssetInfo(assetInfo);
								dependentFinancials.addAsset(this.typesHelper.getAssetType(assetInfo.getAssetType()), asset);
							}
					}
				}
			}

			//expense

			if(hasEmploymentIncome && dependentFinInfo.getExpenses() != null &&
					dependentFinInfo.getExpenses().getExpense() != null){
				List<ExpenseInfo> expenseList = dependentFinInfo.getExpenses().getExpense();
				if (expenseList != null) {
					Iterator expenseIter = expenseList.iterator();

					while (expenseIter.hasNext()) {
						ExpenseInfo expenseInfo = (ExpenseInfo) expenseIter.next();
						if (expenseInfo != null) {
							Expense expense = buildHelper.buildExpenseInfo(expenseInfo);
							dependentFinancials.addExpense(this.typesHelper.getExpenseType(expenseInfo.getExpenseType()), expense);
						}
					}
				}
			}


		    if(dependentFinInfo.isLivedWithPatient() != null){
				dependentFinancials.setLivedWithPatient(dependentFinInfo.isLivedWithPatient());
		    }

		    statement.addDependentFinancials(dependentFinancials);

		}

	 }

	}

	@SuppressWarnings("rawtypes")
	private  void getSpouseFinInfo(FinancialStatement statement, FinancialStatementInfo fStatementInfo, SubmitFormRequest submitFormRequest) throws Exception {

		if(fStatementInfo.getSpouseFinancialsList() != null && fStatementInfo.getSpouseFinancialsList().getSpouseFinancials() !=null){
			logger.info("Spouse financial info is not null");

			List<SpouseFinancialsInfo> spouseList = fStatementInfo.getSpouseFinancialsList().getSpouseFinancials();
			logger.info("spouse list size is " + spouseList.size());
			Iterator itr = spouseList != null ? spouseList.iterator(): null;


			while (itr != null && itr.hasNext()) {

				SpouseFinancialsInfo spouseFinInfo = (SpouseFinancialsInfo)itr.next();
				SpouseFinancials spouseFinancials = new SpouseFinancials();

				if(spouseFinInfo.isLivedWithPatient() != null){
					spouseFinancials.setLivedWithPatient(spouseFinInfo.isLivedWithPatient());

				}

				if(spouseFinancials.getValidDependent()!= null) {
					spouseFinancials.setValidDependent(spouseFinancials.getValidDependent());
				}


				if (spouseFinInfo.getSpouse()!= null ){
				 Spouse spouse = buildSpouse(spouseFinInfo.getSpouse(), submitFormRequest.getForm().getSummary().getPersonInfo().getGender());
				 spouseFinancials.setReportedOn(spouse);
				}
					//		income
				 if(spouseFinInfo.getIncomes() != null &&
						 spouseFinInfo.getIncomes().getIncome() != null){

					List<IncomeInfo> incomeList = spouseFinInfo.getIncomes().getIncome();
					if (incomeList != null) {
						Iterator incomeIter = incomeList.iterator();
						while (incomeIter.hasNext()) {
							IncomeInfo incomeinfo = (IncomeInfo) incomeIter.next();
							if (incomeinfo != null && incomeinfo.getType() != null) {
								Income income = buildHelper.buildIncomeInfo(incomeinfo);
								spouseFinancials.addIncome(this.typesHelper.getIncomeType(incomeinfo.getType()), income);
							}
						}
					}
				 }

					//asset
				 if(spouseFinInfo.getAssets() != null &&
						 spouseFinInfo.getAssets().getAsset() != null){
					List<AssetInfo> assetList = spouseFinInfo.getAssets().getAsset();

					if (assetList != null) {
						Iterator assetIter = assetList.iterator();
						while (assetIter.hasNext()) {
							AssetInfo assetInfo = (AssetInfo)assetIter.next();
							if(assetInfo != null && assetInfo.getAssetType() != null){
								Asset asset = buildHelper.buildAssetInfo(assetInfo);
								spouseFinancials.addAsset(this.typesHelper.getAssetType(assetInfo.getAssetType()), asset);
							}
						}
					}
				 }

					//expense
				 if(spouseFinInfo.getExpenses() != null &&
						 spouseFinInfo.getExpenses().getExpense() != null){
					List<ExpenseInfo> expenseList = spouseFinInfo.getExpenses().getExpense();
					if (expenseList != null) {
						Iterator expenseIter = expenseList.iterator();

						while (expenseIter.hasNext()) {
							ExpenseInfo expenseInfo = (ExpenseInfo) expenseIter.next();
							if (expenseInfo != null) {
								Expense expense = buildHelper.buildExpenseInfo(expenseInfo);
								spouseFinancials.addExpense(this.typesHelper.getExpenseType(expenseInfo.getExpenseType()), expense);
							}
						}
					}
				 }

				 statement.addSpouseFinancials(spouseFinancials);

			 }
		}
	}


	public  Dependent buildDependent(DependentInfo dependentInfo) throws Exception
	{

		Dependent dependent = new Dependent();
		dependent = populateDependentInfo(dependent, dependentInfo);

		return dependent;
	}


	private  Spouse buildSpouse(SpouseInfo spouseInfo, String vetGender) throws Exception {

		Spouse	spouse = new Spouse();

		spouse = populateSpouseInfo(spouse, spouseInfo, vetGender);

		if(spouseInfo.getAddress() != null){
		AddressInfo addressInfo= spouseInfo.getAddress();

		Address address = buildHelper.buildAddressInfo(addressInfo);
		spouse.setAddress(address);
		}

		return spouse;
	}


	/**
	 * Other than spouse and dependednts
	 * @param person
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	private  Dependent populateDependentInfo(Dependent relation, DependentInfo relationInfo) throws Exception {


		Name name = new Name();
		if (relationInfo != null) {
			if(relationInfo.getFamilyName() != null)name.setFamilyName(relationInfo.getFamilyName());
			if(relationInfo.getGivenName() != null) name.setGivenName(relationInfo.getGivenName());
			if(relationInfo.getMiddleName() != null)name.setMiddleName(relationInfo.getMiddleName());
			if(relationInfo.getSuffix() != null)name.setSuffix(relationInfo.getSuffix()); //CCR13238
			relation.setName(name);
		}

		if(relationInfo.getDob() != null && !relationInfo.getDob().isEmpty())relation.setDob(new ImpreciseDate(relationInfo.getDob()));

		if(relationInfo.getStartDate()!= null && !relationInfo.getStartDate().isEmpty())relation.setStartDate(new ImpreciseDate(relationInfo.getStartDate()));

		if(relationInfo.getRelationship() != null){
			relation.setRelationship(this.typesHelper.getRelationship(relationInfo.getRelationship()));
			Relationship rel = this.typesHelper.getRelationship(relationInfo.getRelationship());

			//set dependent gender based on relationship, since gender is not asked on the form
			if (Relationship.CODE_SON.getCode().equals(rel.getCode()) || Relationship.CODE_STEPSON.getCode().equals(rel.getCode())) {
				try {
					relation.setGender(this.typesHelper.getLookupService().getGenderByCode(Gender.MALE.getCode()));
				} catch (Exception e) {
					logger.error("Failed to lookup gender code", e);
					throw new Exception (e);
				}
			} else if (Relationship.CODE_DAUGHTER.getCode().equals(rel.getCode()) || Relationship.CODE_STEPDAUGHTER.getCode().equals(rel.getCode())) {
				try {
					relation.setGender(this.typesHelper.getLookupService().getGenderByCode(Gender.FEMALE.getCode()));

				} catch (Exception e) {
					logger.error("Failed to lookup gender code", e);
					throw new Exception (e);
				}
			}
		}

		if(relationInfo.getSsns() != null && relationInfo.getSsns().getSsn() != null){
			List<SsnInfo> ssnList= relationInfo.getSsns().getSsn();
			if (ssnList != null && ssnList.size() > 0) {
				Iterator ssnItr = ssnList != null ? ssnList.iterator() : null;

				while (ssnItr != null && ssnItr.hasNext()) {
					SsnInfo ssnInfo = (SsnInfo) ssnItr.next();
					SSN ssn = new SSN();
					if(ssnInfo.getSsnText() != null){
						ssn.setSsnText(ssnInfo.getSsnText());
						ssn.setType(typesHelper.getSSNType(SSNType.CODE_ACTIVE.getCode()));
					}
					relation.addSsn(ssn);

				}// end for ssn while


			}// end for ssn if
		}

		return relation;
	}

	@SuppressWarnings("rawtypes")
	private  Spouse populateSpouseInfo(Spouse relation, SpouseInfo relationInfo, String vetGender) throws Exception {


		Name name = new Name();
		if (relationInfo != null) {
			if(relationInfo.getFamilyName() != null)name.setFamilyName(relationInfo.getFamilyName());
			if(relationInfo.getGivenName() != null)name.setGivenName(relationInfo.getGivenName());
			if(relationInfo.getMiddleName() != null)name.setMiddleName(relationInfo.getMiddleName());
			if(relationInfo.getSuffix() != null)name.setSuffix(relationInfo.getSuffix()); //CCR13238

			relation.setName(name);
		}

		if(relationInfo.getDob() != null && !relationInfo.getDob().isEmpty())relation.setDob(new ImpreciseDate(relationInfo.getDob()));

		if (vetGender.equalsIgnoreCase("M")) {
			try {
				relation.setGender(this.typesHelper.getLookupService().getGenderByCode(Gender.FEMALE.getCode()));
			} catch (Exception e) {
				logger.error("Failed to lookup gender code", e);
				throw new Exception (e);
			}
		} else if (vetGender.equalsIgnoreCase("F")) {
			try {
				relation.setGender(this.typesHelper.getLookupService().getGenderByCode(Gender.MALE.getCode()));
			} catch (Exception e) {
				logger.error("Failed to lookup gender code", e);
				throw new Exception (e);
			}
		}


		if(relationInfo.getStartDate()!= null && !relationInfo.getStartDate().isEmpty())relation.setStartDate(new ImpreciseDate(relationInfo.getStartDate()));
		if(relationInfo.getRelationship() != null){
			relation.setRelationship(this.typesHelper.getRelationship(relationInfo.getRelationship()));
		}

		if(relationInfo.getSsns() != null && relationInfo.getSsns().getSsn() != null){
		List<SsnInfo> ssnList= relationInfo.getSsns().getSsn();
		if (ssnList != null && ssnList.size() > 0) {
			Iterator ssnItr = ssnList != null ? ssnList.iterator() : null;

			while (ssnItr != null && ssnItr.hasNext()) {
				SsnInfo ssnInfo = (SsnInfo) ssnItr.next();
				SSN ssn = new SSN();
				if(ssnInfo.getSsnText() != null){
					ssn.setSsnText(ssnInfo.getSsnText());
					ssn.setType(typesHelper.getSSNType(SSNType.CODE_ACTIVE.getCode()));
				}
				relation.addSsn(ssn);

			}// end for ssn while


		}// end for ssn if
	  }

		return relation;
	}

}
