/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.esr.common.rule.service;

import gov.va.med.esr.common.model.financials.FinancialStatement;
import gov.va.med.esr.common.model.financials.Hardship;
import gov.va.med.esr.common.model.financials.IncomeTest;
import gov.va.med.esr.common.model.lookup.AddressType;
import gov.va.med.esr.common.model.lookup.IncomeTestSource;
import gov.va.med.esr.common.model.lookup.IncomeTestType;
import gov.va.med.esr.common.model.lookup.MeansTestStatus;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.lookup.IncomeTestSource.Code;
import gov.va.med.esr.common.model.party.Address;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.util.RuleAbstractTestCase;
import gov.va.med.fw.service.ServiceException;

import java.util.Calendar;
import java.util.Date;

/**
 * Abstract Financials Test
 * @author DNS   MANSOG
 * @version 1.0
 */
public abstract class AbstractFinancialTest
    extends RuleAbstractTestCase {

    private VAFacility hecFacility = null;

    public AbstractFinancialTest(String testName) throws Exception {
        super(testName);
    }

	protected abstract Person invokeFinancialRuleService(Integer incomeYear,
            VAFacility facility, Person incoming, Person onFile)
            throws Exception;


    protected VAFacility getHECFacility() throws Exception {
        if (hecFacility == null)
            hecFacility = getVaFacility(VAFacility.CODE_HEC);
        return hecFacility;
    }

    protected MeansTestStatus getMeansTestStatus(MeansTestStatus.Code code)
            throws Exception {
        return getLookupService().getMeansTestStatusByCode(code.getName());
    }

    protected IncomeTestType getTestType(IncomeTestType.Code code)
            throws Exception {
        return getLookupService().getIncomeTestTypeByCode(code.getName());
    }

    protected IncomeTestSource getTestSource(Code code) throws Exception {
        return getLookupService().getIncomeTestSourceByCode(code.getName());
    }

    protected FinancialStatement buildFinancialStatementData(Integer incomeYear, Person person)
            throws Exception {
        FinancialStatement stmt = person.getFinancialStatement(incomeYear);
        if (stmt == null) {
            stmt = createFinancialStatement();
            person.setFinancialStatement(incomeYear, stmt);
        }
        stmt.addSpouseFinancials(createSpouseFinancials());
        stmt.addDependentFinancials(createDependentFinancials());
        stmt.addDependentFinancials(createDependentFinancials());
        
        return stmt;
    }
    
    protected IncomeTest buildIncomeTestData(Integer incomeYear, Person person,
            IncomeTestType testType, IncomeTestSource source,
            MeansTestStatus mtStatus, VAFacility facility) throws Exception {
        IncomeTest incomeTest = person.getIncomeTest(incomeYear);
        if (incomeTest == null) {
            incomeTest = new IncomeTest();
            incomeTest.setIncomeYear(incomeYear);
            person.setIncomeTest(incomeYear, incomeTest);
        }
        setIncomeTestProps(incomeTest, testType, source, mtStatus, facility);

        Hardship hardship = buildHardshipData(facility);
        incomeTest.setHardship(hardship);

        return incomeTest;
    }

    protected Hardship buildHardshipData(VAFacility facility) {
        Hardship hardship = createHardship("Hardship");
        hardship.setReviewDate(new Date());
        hardship.setSiteGrantingHardship(facility);
        return hardship;
    }

    protected IncomeTest buildIncomeTestData(Integer incomeYear, Person person,
            IncomeTestType testType, IncomeTestSource source,
            MeansTestStatus mtStatus, VAFacility facility, Date completedDate,
            Date lastEditTime, Date effectiveDate) throws Exception {
        IncomeTest incomeTest = person.getIncomeTest(incomeYear);
        if (incomeTest == null) {
            incomeTest = new IncomeTest();
            incomeTest.setIncomeYear(incomeYear);
            person.setIncomeTest(incomeYear, incomeTest);
        }
        setIncomeTestProps(incomeTest, testType, source, mtStatus, facility,
                completedDate, lastEditTime, effectiveDate);
        return incomeTest;
    }

    protected Person savePerson(Person person) throws ServiceException,
            Exception {
        return getPersonService().save(person);
    }

    protected Person buildSimplePerson() throws Exception {
        Person person = super.buildSimplePerson();
        Address adr = createAddress(getLookupService().getAddressTypeByCode(
                AddressType.CODE_PERMANENT_ADDRESS.getName()));
        person.addAddress(adr);
        return person;
    }

    protected Date addYearToDate(Date completedDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(completedDate);
        calendar.add(Calendar.YEAR, 1);
        if (calendar.get(Calendar.MONTH) == Calendar.FEBRUARY
                && calendar.get(Calendar.DAY_OF_MONTH) == 29) {
            calendar.set(Calendar.DAY_OF_MONTH, 28);
        }
        return calendar.getTime();
    }
}