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

import gov.va.med.esr.common.model.ee.Eligibility;
import gov.va.med.esr.common.model.ee.EnrollmentDetermination;
import gov.va.med.esr.common.model.lookup.EligibilityType;
import gov.va.med.esr.common.model.lookup.EnrollmentPriorityGroup;
import gov.va.med.esr.common.model.lookup.EnrollmentPrioritySubGroup;
import gov.va.med.esr.common.model.lookup.EnrollmentStatus;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.persistent.hibernate.AbstractKeyedEntityDAOTestCase;
import gov.va.med.fw.model.AbstractKeyedEntity;

import java.math.BigDecimal;

public class EnrollmentInputParameterTest extends
        AbstractKeyedEntityDAOTestCase {

    /**
     * Side effect is also to test
     * EnrollmentInputParameter.getEarliestVerifiedEnrollmentDetermination()
     * 
     * @throws Exception
     */
    public void testGetEarliestEnrollmentPriority() throws Exception {
        EnrollmentInputParameter enrollmentInputParameter = new EnrollmentInputParameter();

        // no enrollment determinations
        Person person = this.buildSimplePerson();
        assertEquals(null, enrollmentInputParameter
                .getEarliestEnrollmentPriority(person));

        // 2 cancelled decline records, earliest verified is 8
        person = this.buildSimplePerson();
        person.setEnrollmentDetermination(createEnrollmentDetermination(
                EnrollmentStatus.CODE_CANCELLED_DECLINED,
                EnrollmentPriorityGroup.GROUP_1,
                EnrollmentPrioritySubGroup.SUBGROUP_A, new BigDecimal(1)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(EnrollmentStatus.CODE_VERIFIED,
                        EnrollmentPriorityGroup.GROUP_2,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(2)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(
                        EnrollmentStatus.CODE_CANCELLED_DECLINED,
                        EnrollmentPriorityGroup.GROUP_3,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(3)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(EnrollmentStatus.CODE_VERIFIED,
                        EnrollmentPriorityGroup.GROUP_8,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(4)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(EnrollmentStatus.CODE_VERIFIED,
                        EnrollmentPriorityGroup.GROUP_7,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(5)));
        assertEquals(EnrollmentPriorityGroup.GROUP_8.getCode(),
                enrollmentInputParameter.getEarliestEnrollmentPriority(person));

        // 2 cancelled decline records, no earliest verified
        person = this.buildSimplePerson();
        person.setEnrollmentDetermination(createEnrollmentDetermination(
                EnrollmentStatus.CODE_CANCELLED_DECLINED,
                EnrollmentPriorityGroup.GROUP_1,
                EnrollmentPrioritySubGroup.SUBGROUP_A, new BigDecimal(1)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(EnrollmentStatus.CODE_VERIFIED,
                        EnrollmentPriorityGroup.GROUP_2,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(2)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(
                        EnrollmentStatus.CODE_CANCELLED_DECLINED,
                        EnrollmentPriorityGroup.GROUP_3,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(3)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(EnrollmentStatus.CODE_INACTIVE,
                        EnrollmentPriorityGroup.GROUP_8,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(4)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(
                        EnrollmentStatus.CODE_NOT_ELIGIBLE,
                        EnrollmentPriorityGroup.GROUP_7,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(5)));
        assertEquals(null, enrollmentInputParameter
                .getEarliestEnrollmentPriority(person));

        // no cancelled declined, verified record is second enrollment
        person = this.buildSimplePerson();
        person.setEnrollmentDetermination(createEnrollmentDetermination(
                EnrollmentStatus.CODE_DECEASED,
                EnrollmentPriorityGroup.GROUP_1,
                EnrollmentPrioritySubGroup.SUBGROUP_A, new BigDecimal(1)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(EnrollmentStatus.CODE_VERIFIED,
                        EnrollmentPriorityGroup.GROUP_2,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(2)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(EnrollmentStatus.CODE_VERIFIED,
                        EnrollmentPriorityGroup.GROUP_8,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(3)));
        person.getEnrollmentDeterminations().add(
                createEnrollmentDetermination(EnrollmentStatus.CODE_VERIFIED,
                        EnrollmentPriorityGroup.GROUP_7,
                        EnrollmentPrioritySubGroup.SUBGROUP_A,
                        new BigDecimal(4)));
        assertEquals(EnrollmentPriorityGroup.GROUP_2.getCode(),
                enrollmentInputParameter.getEarliestEnrollmentPriority(person));
    }

    protected EnrollmentDetermination createEnrollmentDetermination(
            EnrollmentStatus.Code enrollmentStatus,
            EnrollmentPriorityGroup.Code enrollmentPriorityGroup,
            EnrollmentPrioritySubGroup.Code enrollmentPrioritySubGroup,
            BigDecimal identifier) throws Exception {
        EligibilityType eligibilityType = (EligibilityType) this
                .getLookupService().getByCode(
                        EligibilityType.class,
                        EligibilityType.SERVICE_CONNECTED_50_TO_100_PERCENT
                                .getCode());

        Eligibility eligibility = new Eligibility();
        eligibility.setPrimary();
        eligibility.setType(eligibilityType);

        EnrollmentDetermination enrollmentDetermination = this
                .createEnrollmentDetermination();
        enrollmentDetermination.setPrimaryEligiblity(eligibility);
        enrollmentDetermination.setEnrollmentStatus((EnrollmentStatus) this
                .getLookupService().getByCode(EnrollmentStatus.class,
                        enrollmentStatus));
        enrollmentDetermination.setPriorityGroup((EnrollmentPriorityGroup) this
                .getLookupService().getByCode(EnrollmentPriorityGroup.class,
                        enrollmentPriorityGroup));
        enrollmentDetermination
                .setPrioritySubGroup((EnrollmentPrioritySubGroup) this
                        .getLookupService().getByCode(
                                EnrollmentPrioritySubGroup.class,
                                enrollmentPrioritySubGroup));
        enrollmentDetermination.setIdentifier(identifier);
        return enrollmentDetermination;
    }

    protected void modifyTestObject(AbstractKeyedEntity obj) throws Exception {
        // TODO Auto-generated method stub

    }

    protected AbstractKeyedEntity setUpTestObject() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }
}
