package gov.va.med.esr.xml;

import gov.va.med.esr.service.external.person.AddressInfo;
import gov.va.med.esr.service.external.person.AssetInfo;
import gov.va.med.esr.service.external.person.ConsentInfo;
import gov.va.med.esr.service.external.person.EESummary;
import gov.va.med.esr.service.external.person.ExpenseInfo;
import gov.va.med.esr.service.external.person.FinancialStatementInfo;
import gov.va.med.esr.service.external.person.MonetaryBenefitInfo;
import gov.va.med.esr.service.external.person.NameInfo;
import gov.va.med.esr.service.external.person.NonPrimaryFinancialStatementInfo;
import gov.va.med.esr.service.external.person.PersonInfo;
import gov.va.med.esr.service.external.person.PhoneInfo;
import gov.va.med.esr.service.external.person.SpouseFinancialsInfo;
import gov.va.med.esr.service.external.person.SpouseInfo;
import gov.va.med.esr.service.external.person.VamcInfo;
import gov.va.med.esr.service.external.person.collections.MonetaryBenefitCollection;
import gov.va.med.esr.service.external.person.collections.PhoneCollection;
import gov.va.med.esr.webservices.generated.GetEESummaryResponse;
import gov.va.med.esr.xml.mapping.castor.DateHandler;
import gov.va.med.esr.xml.mapping.castor.DateTimeHandler;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;

import javax.xml.bind.JAXBException;

import org.springframework.core.io.ClassPathResource;

import junit.framework.Assert;
/* 
 * IMPORTANT NOTE TO DEVELOPERS: 
 * This transformer class JAXB generated classes.  The JAXB generated are not check into source control.
 * You can generate the JAXB classes by running the the build-eesummary-jaxb-classes.xml file.
 */
public class EESummaryTestHelper {	
	//TODO: NEED TO TEST eeSummary.financialsInfo.financialStatement.incomes.income.incomeReportDate **
	public static void assertPerson(PersonInfo person){
		String expectedFirstName = "p:firstName",
				expectedMiddleName = "p:middleName",
				expectedLastName = "p:lastName",
				expectedPrefix = "p:prefix",
				expectedSuffix = "p:suffix",
				expectedGender = "p:gender",
				expectedDob = "p:dob",
				expectedSsaVerificationStatus = "p:ssaVerificationStatus",
				expectedSsaVerificationDate = "2001-01-01",
				expectedMothersMaidenName = "p:mothersMaidenName",
				expectedPlaceOfBirthCity = "p:placeOfBirthCity",
				expectedPlaceOfBirthState = "p:placeOfBirthState";
		
		String[][] expectedVamcInfoData = {
				{"p:dfnNumber", "p:facilityNumber", "2001-01-01", "2001-01-01"}
		};
		
		String[][] expectedOtherNames = {
				{"p:otherName"}
		};
		
		
		Assert.assertNotNull(person);
		Assert.assertEquals(expectedFirstName, person.getFirstName());
		Assert.assertEquals(expectedMiddleName, person.getMiddleName());
		Assert.assertEquals(expectedLastName, person.getLastName());
		Assert.assertEquals(expectedPrefix, person.getPrefix());
		Assert.assertEquals(expectedSuffix, person.getSuffix());
		Assert.assertEquals(expectedGender, person.getGender());
		Assert.assertEquals(expectedDob, person.getDob());
		Assert.assertEquals(expectedSsaVerificationStatus, person.getSsaVerificationStatus());
		Assert.assertEquals(expectedSsaVerificationDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(person.getSsaVerificationDate()));
		Assert.assertEquals(expectedMothersMaidenName, person.getMothersMaidenName());
		Assert.assertEquals(expectedPlaceOfBirthCity, person.getPlaceOfBirthCity());
		Assert.assertEquals(expectedPlaceOfBirthState, person.getPlaceOfBirthState());
		Assert.assertNotNull(person.getVamcData());
		Assert.assertNotNull(person.getVamcData().getVamcInfo());		
		Assert.assertEquals(expectedVamcInfoData.length, person.getVamcData().getVamcInfo().length);
		for(VamcInfo vamcInfo: person.getVamcData().getVamcInfo()){
			Assert.assertEquals(expectedVamcInfoData[0][0], vamcInfo.getDfnNumber());
			Assert.assertEquals(expectedVamcInfoData[0][1], vamcInfo.getFacilityNumber());
			Assert.assertEquals(expectedVamcInfoData[0][2], (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(vamcInfo.getLastVisitDate()));
			Assert.assertEquals(expectedVamcInfoData[0][3], (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(vamcInfo.getVamcReportDate()));
		}
		Assert.assertNotNull(person.getNames());
		Assert.assertNotNull(person.getNames().getName());		
		Assert.assertEquals(expectedOtherNames.length, person.getNames().getName().length);
		for(NameInfo nameInfo: person.getNames().getName()){
			Assert.assertEquals(expectedOtherNames[0][0], nameInfo.getOtherName());
		}
	}

	public static void assertConsent(ConsentInfo consentInfo) {
		String expectedConsentAuthCode = "p:consentAuthCode",
				expectedConsentImagingSite = "p:consentImagingSite",
				expectedConsentImageIndexNumber = "p:consentImageIndexNumber",
				expectedConsentReportDate = "2001-01-01",
				expectedConsentLastUpdateDate = "2001-01-01";
				
		Assert.assertNotNull(consentInfo);
		Assert.assertEquals(expectedConsentAuthCode, consentInfo.getConsentAuthCode());
		Assert.assertEquals(expectedConsentImagingSite, consentInfo.getConsentImagingSite());
		Assert.assertEquals(expectedConsentImageIndexNumber, consentInfo.getConsentImageIndexNumber());
		Assert.assertEquals(expectedConsentReportDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(consentInfo.getConsentReportDate()));
		Assert.assertEquals(expectedConsentLastUpdateDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(consentInfo.getConsentLastUpdateDate()));
	}
	
	public static void assertAddress(AddressInfo addressInfo){
		String expectedCity = "p:city",
				expectedCountry = "p:country",
				expectedCounty = "p:county",
				expectedLine1 = "p:line1",
				expectedLine2 = "p:line2",
				expectedLine3 = "p:line3",
				expectedPostalCode = "p:postalCode",
				expectedProvinceCode = "p:provinceCode",
				expectedState = "p:state",
				expectedZipCode = "p:zipCode",
				expectedZipPlus4 = "p:zipPlus4",
				expectedAddressChangeDateTime = "2001-12-31T12:00:00",
				expectedAddressChangeEffectiveDate = "p:addressChangeEffectiveDate",
				expectedAddressChangeSite = "p:addressChangeSite",
				expectedAddressChangeSource = "p:addressChangeSource",
				expectedAddressTypeCode = "p:addressTypeCode",
				expectedBadAddressReason = "p:badAddressReason",
				expectedEndDate = "p:endDate",
				expectedPhoneNumber = "p:phoneNumber",
				expectedContactMethodType = "p:contactMethodType",
				expectedContactMethodReportDate = "2001-01-01";
		
		String[] expectedConfidentialAddressCategoryType = {"p:confidentialAddressCategoryType"};
		
		Assert.assertNotNull(addressInfo);
		Assert.assertEquals(expectedCity, addressInfo.getCity());
		Assert.assertEquals(expectedCountry, addressInfo.getCountry());
		Assert.assertEquals(expectedCounty, addressInfo.getCounty());
		Assert.assertEquals(expectedLine1, addressInfo.getLine1());
		Assert.assertEquals(expectedLine2, addressInfo.getLine2());
		Assert.assertEquals(expectedLine3, addressInfo.getLine3());
		Assert.assertEquals(expectedPostalCode, addressInfo.getPostalCode());
		Assert.assertEquals(expectedProvinceCode, addressInfo.getProvinceCode());
		Assert.assertEquals(expectedState, addressInfo.getState());
		Assert.assertEquals(expectedZipCode, addressInfo.getZipCode());
		Assert.assertEquals(expectedZipPlus4, addressInfo.getZipPlus4());
		Assert.assertEquals(expectedAddressChangeDateTime, (new SimpleDateFormat(DateTimeHandler.YYYY_MM_DDTHH_MM_SS_FORMAT)).format(addressInfo.getAddressChangeDateTime()));
		Assert.assertEquals(expectedAddressChangeEffectiveDate, addressInfo.getAddressChangeEffectiveDate());
		Assert.assertEquals(expectedAddressChangeSite, addressInfo.getAddressChangeSite());
		Assert.assertEquals(expectedAddressChangeSource, addressInfo.getAddressChangeSource());
		Assert.assertEquals(expectedAddressTypeCode, addressInfo.getAddressTypeCode());
		Assert.assertEquals(expectedBadAddressReason, addressInfo.getBadAddressReason());
		Assert.assertEquals(expectedEndDate, addressInfo.getEndDate());
		Assert.assertEquals(expectedPhoneNumber, addressInfo.getPhoneNumber());
		Assert.assertEquals(expectedContactMethodType, addressInfo.getContactMethodType());
		Assert.assertEquals(expectedContactMethodReportDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(addressInfo.getContactMethodReportDate()));
		Assert.assertNotNull(addressInfo.getConfidentialAddressCategories());
		Assert.assertNotNull(addressInfo.getConfidentialAddressCategories().getConfidentialAddressCategoryType());		
		Assert.assertEquals(expectedConfidentialAddressCategoryType.length, addressInfo.getConfidentialAddressCategories().getConfidentialAddressCategoryType().length);
		for(String actualConfidentialAddressCategoryType: addressInfo.getConfidentialAddressCategories().getConfidentialAddressCategoryType()){
			Assert.assertEquals(expectedConfidentialAddressCategoryType[0], actualConfidentialAddressCategoryType);
		}
	}

	public static void assertPhone(PhoneInfo phone) {
		String expectedPhoneNumber = "p:phoneNumber",
				expectedType = "p:type",
				expectedPhoneNumberReportDate = "2001-01-01";
		
		Assert.assertNotNull(phone);
		Assert.assertEquals(expectedPhoneNumber, phone.getPhoneNumber());
		Assert.assertEquals(expectedType, phone.getType());
		Assert.assertEquals(expectedPhoneNumberReportDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(phone.getPhoneNumberReportDate()));			
	}

	public static void assertMonetartyBenefit(MonetaryBenefitInfo monetaryBenefitInfo) {
		String expectedMonetaryBenefitIndicator = "true",
				expectedType = "p:type",
				expectedMonetaryBenefitReportDate = "2001-01-01";
		
		Assert.assertNotNull(monetaryBenefitInfo);
		Assert.assertEquals(expectedMonetaryBenefitIndicator, monetaryBenefitInfo.getMonetaryBenefitIndicator().toString());
		Assert.assertEquals(expectedType, monetaryBenefitInfo.getType());
		Assert.assertEquals(expectedMonetaryBenefitReportDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(monetaryBenefitInfo.getMonetaryBenefitReportDate()));
	}

	public static void assertFinancialStatement(FinancialStatementInfo financialStatement) {
		int expectedInpatientDays = 0, expectedOutpatientDays = 0;
		String expectedLastVisitDate = "2001-01-01", expectedVamcReportDate = "2001-01-01";
		
		Assert.assertNotNull(financialStatement);
		Assert.assertEquals(expectedInpatientDays, financialStatement.getInpatientDays().intValue());
		Assert.assertEquals(expectedOutpatientDays, financialStatement.getOutpatientDays().intValue());
		Assert.assertEquals(expectedLastVisitDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(financialStatement.getLastVisitDate()));
		Assert.assertEquals(expectedVamcReportDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(financialStatement.getVamcReportDate()));		
	}

	public static void assertExpense(ExpenseInfo expenseInfo) {
		double expectedAmount = 0.0;
		String expectedExpenseType = "p:expenseType";
		String expectedExpenseReportDate = "2001-01-01";
		
		Assert.assertNotNull(expenseInfo);
		Assert.assertEquals(expectedAmount, expenseInfo.getAmount().doubleValue());
		Assert.assertEquals(expectedExpenseType, expenseInfo.getExpenseType());
		Assert.assertEquals(expectedExpenseReportDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(expenseInfo.getExpenseReportDate()));		
	}

	public static void assertAsset(AssetInfo assetInfo) {
		double expectedAmount = 0.0;
		String expectedAssetType = "p:assetType";
		String expectedAssetReportDate = "2001-01-01";
		
		Assert.assertNotNull(assetInfo);
		Assert.assertEquals(expectedAmount, assetInfo.getAmount().doubleValue());
		Assert.assertEquals(expectedAssetType, assetInfo.getAssetType());
		Assert.assertEquals(expectedAssetReportDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(assetInfo.getAssetReportDate()));
	}

	public static void assertNonPrimaryFinancialStatementInfo(NonPrimaryFinancialStatementInfo nonPrimaryFinancialStatementInfo) {
		int expectedIncomeYear = 0, expectedInpatientDays = 0, expectedOutpatientDays = 0;
		String expectedFacilityVisitedCode = "p:facilityVisitedCode", expectedLastVisitDate = "2001-01-01",
				expectedVamcReportDate = "2001-01-01";
		
		Assert.assertNotNull(nonPrimaryFinancialStatementInfo);
		Assert.assertEquals(expectedFacilityVisitedCode, nonPrimaryFinancialStatementInfo.getFacilityVisitedCode());
		Assert.assertEquals(expectedIncomeYear, nonPrimaryFinancialStatementInfo.getIncomeYear().intValue());
		Assert.assertEquals(expectedInpatientDays, nonPrimaryFinancialStatementInfo.getInpatientDays().intValue());
		Assert.assertEquals(expectedOutpatientDays, nonPrimaryFinancialStatementInfo.getOutpatientDays().intValue());
		Assert.assertEquals(expectedLastVisitDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(nonPrimaryFinancialStatementInfo.getLastVisitDate()));
		Assert.assertEquals(expectedVamcReportDate, (new SimpleDateFormat(DateHandler.YYYY_MM_DD_FORMAT)).format(nonPrimaryFinancialStatementInfo.getVamcReportDate()));
	}

	public static EESummary createMockEESummary() {
		
		return null;
	}
	/* 
	 * IMPORTANT NOTE TO DEVELOPERS: 
	 * This transformer class JAXB generated classes.  The JAXB generated are not check into source control.
	 * You can generate the JAXB classes by running the the build-eesummary-jaxb-classes.xml file.
	 */
	public static EESummary createMockEESummaryWithAbsoluteFilePath(String xmlMockDataFileName) throws IOException, JAXBException {
		FileInputStream inputStream = new FileInputStream(new File(xmlMockDataFileName));
		Class<GetEESummaryResponse> klass = GetEESummaryResponse.class;
		GetEESummaryResponse response = JAXBUtility.getInstance().unmarshalJaxbXmlElement(klass, inputStream);		
		return EESummaryJAXBTransformer.createEESummary(response.getSummary());
	}
	/* 
	 * IMPORTANT NOTE TO DEVELOPERS: 
	 * This transformer class JAXB generated classes.  The JAXB generated are not check into source control.
	 * You can generate the JAXB classes by running the the build-eesummary-jaxb-classes.xml file.
	 */
	public static EESummary createMockEESummary(String xmlMockDataFileName) throws IOException, JAXBException {
		FileInputStream inputStream = new FileInputStream((new ClassPathResource(xmlMockDataFileName)).getFile());
		Class<GetEESummaryResponse> klass = GetEESummaryResponse.class;
		GetEESummaryResponse response = JAXBUtility.getInstance().unmarshalJaxbXmlElement(klass, inputStream);		
		return EESummaryJAXBTransformer.createEESummary(response.getSummary());
	}
}
