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

// Java classes
import java.util.Collection;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.Validate;

import gov.va.med.esr.common.model.ee.ClinicalDetermination;
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.ee.MilitaryService;
import gov.va.med.esr.common.model.ee.MonetaryBenefit;
import gov.va.med.esr.common.model.ee.PurpleHeart;
import gov.va.med.esr.common.model.financials.IncomeTest;
import gov.va.med.esr.common.model.lookup.DecorationStatus;
import gov.va.med.esr.common.model.lookup.EligibilityStatus;
import gov.va.med.esr.common.model.lookup.EligibilityStatusPendVerfiReason;
import gov.va.med.esr.common.model.lookup.EnrollmentCategory;
import gov.va.med.esr.common.model.lookup.EnrollmentStatus;
import gov.va.med.esr.common.model.lookup.ServicePeriod;
import gov.va.med.esr.common.model.lookup.State;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.PersonTraits;
import gov.va.med.esr.common.model.person.SSN;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.builder.BuilderException;
import gov.va.med.esr.common.model.lookup.MilitaryServiceQueryStatus;


/**
 * Project: Common
 * 
 * @author DNS   LEV
 * @version 1.0
 */
public interface PersonHelperService {
    /**
     * Returns a person's eligibility status
     * 
     * @param person
     *            A person from which eligibility status is obtained
     * @return An eligibility status to which a person belongs
     * @throws ServiceException
     *             If failed to lookup an eligibility status
     */
    public EligibilityStatus getEligibilityStatus(Person person)
            throws ServiceException;

    /**
     * Returns a purple heart status of a person
     * 
     * @param person
     *            A person to look up a process status
     * @return ProcessStatus The process status of type purple heart
     * @throws ServiceException
     *             If failed to lookup a process status and type
     */
    public DecorationStatus getPurpleHeartStatus(Person person)
            throws ServiceException;

    /**
     * Returns a set of rated disabilities from a person or an empty collection
     * if a person doesn't have any service connection award.
     * 
     * @param person
     *            A person to look up
     * @return A collection of rated disabilities
     */
    public Set getRatedDisabilities(Person person);

    /**
     * This method gets a Aid and Attendant benefit from the person graph.
     * 
     * @param person
     *            The person who has monetary benefit.
     * @return The monetary benefit of a Aid and Attendant type.
     * @throws ServiceException
     *             If failed to lookup a monetary benefit
     */
    public MonetaryBenefit getAABenefit(Person person) throws ServiceException;

    /**
     * This method gets a house bound benefit from the person graph.
     * 
     * @param person
     *            The person who has monetary benefit.
     * @return The monetary benefit of a house bound type.
     * @throws ServiceException
     *             If failed to lookup a monetary benefit
     */
    public MonetaryBenefit getHouseboundBenefit(Person person)
            throws ServiceException;

    /**
     * This method gets a house bound benefit from the person graph.
     * 
     * @param person
     *            The person who has monetary benefit.
     * @return The monetary benefit of a house bound type.
     * @throws ServiceException
     *             If failed to lookup a monetary benefit
     */
    public MonetaryBenefit getDisabilityBenefit(Person person)
            throws ServiceException;

    /**
     * This method gets a VA pension benefit from the person graph.
     * 
     * @param person
     *            The person who has monetary benefit.
     * @return The monetary benefit of a VA pension type.
     * @throws ServiceException
     *             If failed to lookup a monetary benefit
     */
    public MonetaryBenefit getVAPensionBenefit(Person person)
            throws ServiceException;

    public Person uploadData(Person onSitePerson, Person onFilePerson)
            throws ServiceException;

    /**
     * Sets the AAC indicator in a Process State object that is part of a
     * person's process states. Upon completion of method, the person will have
     * a new process state with the new process status of type AAC indicator.
     * 
     * @param code
     *            A process status code to set
     * @param person
     *            The person to which a process status belongs
     * @throws ServiceException
     *             If failed to lookup a process status
     */
    public void setAACIndicator(String code, Person person)
            throws ServiceException;

    /**
     * Sets the eligibility status in a Process State object that is part of a
     * person's process states. Upon completion of method, the person will have
     * a new process state with the new process status of type eligibility
     * status.
     * 
     * @param code
     *            A process status code to set
     * @param person
     *            The person to which a process status belongs
     * @throws ServiceException
     *             If failed to lookup a process status
     */
    public void setEligibilityStatus(String code, Person person)
            throws ServiceException;

    /**
     * Sets the enrollment status in a Process State object that is part of a
     * person's process states. Upon completion of method, the person will have
     * a new process state with the new process status of type eligibility
     * status.
     * 
     * @param code
     *            A process status code to set
     * @param person
     *            The person to which a process status belongs
     * @throws ServiceException
     *             If failed to lookup a process status
     */
    public void setEnrollmentStatus(String code, Person person)
            throws ServiceException;

    /**
     * @param code
     * @param enrollment
     * @throws ServiceException
     */
    public void setEnrollmentStatus(String code,
            EnrollmentDetermination enrollment) throws ServiceException;

    /**
     * lookup the enrollment priority identified by the code and set the initial
     * priority on the enrollment determination
     * 
     * @param code
     *            identifies the priority
     * @param enrollmentDetermination
     *            enrollment determination for which initial priority will be
     *            set
     * @throws ServiceException
     *             thrown if unable to look up the enrollment priority code
     */
    public void setInitialEnrollmentPriority(String code,
            EnrollmentDetermination enrollmentDetermination)
            throws ServiceException;

    /**
     * lookup the enrollment sub priority identified by the code and set the
     * initial sub priority on the enrollment determination
     * 
     * @param code
     *            identifies the sub priority
     * @param enrollmentDetermination
     *            enrollment determination for which initial sub priority will
     *            be set
     * @throws ServiceException
     *             thrown if unable to look up the enrollment sub priority code
     * @throws IllegalArgumentException
     *             thrown if code or enrollmentDetermination are null
     */
    public void setInitialEnrollmentPrioritySubGroup(String code,
            EnrollmentDetermination enrollmentDetermination)
            throws ServiceException;

    /**
     * Sets the purple heart status in a Process State object that is part of a
     * person's process states. Upon completion of method, the person will have
     * a new process state with the new process status of type purple heart
     * status.
     * 
     * @param code
     *            A process status code to set
     * @param person
     *            The person to which a process status belongs
     * @throws ServiceException
     *             If failed to lookup a process status
     * @throws IllegalArgumentException
     *             thrown if code or enrollmentDetermination are null
     */
    public void setPurpleHeartStatus(String code, Person person)
            throws ServiceException;

    /**
     * Adds a VA pension to a person
     * 
     * @param person
     *            A person to add a VA pension
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public MonetaryBenefit addVAPension(Person person) throws ServiceException;

    /**
     * Adds an AA benefit to a person
     * 
     * @param person
     *            A person to add an AA benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public MonetaryBenefit addAABenefit(Person person) throws ServiceException;

    /**
     * Removes an AA benefit to a person
     * 
     * @param person
     *            A person to remove an AA benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public void removeAABenefit(Person person) throws ServiceException;

    /**
     * Adds a House bound benefit to a person
     * 
     * @param person
     *            A person to add a house bound benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public MonetaryBenefit addHouseboundBenefit(Person person)
            throws ServiceException;

    /**
     * Removes a house bound benefit to a person
     * 
     * @param person
     *            A person to remove a house bound benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public void removeHouseboundBenefit(Person person) throws ServiceException;

    /**
     * Adds a VA disability benefit to a person
     * 
     * @param person
     *            A person to add a VA disability benefit
     * @throws ServiceException
     *             if failed to look up a monetary benefit
     */
    public MonetaryBenefit addVADisability(Person person)
            throws ServiceException;

    /**
     * Sets a verification source to a new person
     * 
     * @param code
     *            A verification source code to lookup a verification source
     * @param person
     *            A person to set a verfification source
     * @throws ServiceException
     *             if failed to look up an eligibility verification source
     */
    public void setVerificationSource(String code, Person person)
            throws ServiceException;

    /**
     * Sets a verification method
     * 
     * @param method
     *            A verification method to set in an eligibiility verification
     * @param person
     *            A person to set a verfification source
     * @throws ServiceException
     *             if failed to look up an eligibility verification source
     */
    public void setVerificationMethod(String method, Person person)
            throws ServiceException;

    /**
     * Sets a verification facility
     * 
     * @param code
     *            A verification code to lookup a facility
     * @param person
     *            A person to set a verfification facility
     * @throws ServiceException
     *             if failed to look up an eligibility verification facility
     */
    public void setVerificationFacility(String code, Person person)
            throws ServiceException;

    /**
     * Sets a verification facility
     * 
     * @param code
     *            A verification code to lookup a facility
     * @param person
     *            A person to set a verfification facility
     * @throws ServiceException
     *             if failed to look up an eligibility verification facility
     */
    public void setVerificationFacility(VAFacility facility, Person person)
            throws ServiceException;

    /**
     * Sets a priority sub group in an enrollment determination
     * 
     * @param code
     *            A priority sub group code to lookup
     * @param enrollmentDetermination
     *            An enrollment determination to set a priority sub group
     * @throws ServiceException
     *             if failed to look up a priority sub group
     */
    public void setEnrollmentPrioritySubGroup(String code,
            EnrollmentDetermination enrollmentDetermination)
            throws ServiceException;

    /**
     * Sets a priority group in an enrollment determination
     * 
     * @param code
     *            A priority group code to lookup
     * @param enrollmentDetermination
     *            An enrollment determination to set a priority group
     * @throws ServiceException
     *             if failed to look up a priority group
     */
    public void setEnrollmentPriority(String code,
            EnrollmentDetermination enrollmentDetermination)
            throws ServiceException;

    /**
     * Creates an eligibility type for the specific type code
     * 
     * @param code
     *            An eligibility type code
     * @return An eligibility
     * @throws ServiceException
     *             thrown if failed to look up an eligibility type
     */
    public Eligibility createEligibility(String code) throws ServiceException;

    /**
     * Create an Other eligibility
     * 
     * @param code
     * @return
     * @throws ServiceException
     */
    public Eligibility createOtherEligibility(String code)
            throws ServiceException;

 
    /**
     * Returns a person's enrollment status
     * 
     * @param person
     *            A person from which enrollment status is obtained
     * @return An enrollment status to which a person belongs
     * @throws ServiceException
     *             If failed to lookup an enrollment status
     */
    public EnrollmentStatus getEnrollmentStatus(Person person)
            throws ServiceException;

    /**
     * Returns a person's enrollment status
     * 
     * @param person
     *            A person from which enrollment status is obtained
     * @return An enrollment status to which a person belongs
     * @throws ServiceException
     *             If failed to lookup an enrollment status
     */
    public EnrollmentCategory getEnrollmentCategory(Person person)
            throws ServiceException;

    /**
     * Set the enrollment category for a person.
     * 
     * @param category
     *            A category to set
     * @param person
     *            The person who owns the category
     * @throws ServiceException
     */
    public void setEnrollmentCategory(String category, Person person)
            throws ServiceException;

    /**
     * @param category
     * @param enrollment
     * @throws ServiceException
     */
    public void setEnrollmentCategory(String category,
            EnrollmentDetermination enrollment) throws ServiceException;

    /**
     * Set the enrollment source of an enrollment.
     * 
     * @param source
     *            The source to set.
     * @param enrollment
     *            The enrollment who owns the source.
     * @throws ServiceException
     */
    public void setEnrollmentSource(String source,
            EnrollmentDetermination enrollment) throws ServiceException;

    /**
     * Set the "facility received from" in an enrollment determination.
     * 
     * @param facility
     *            The facility to set
     * @param enrollment
     *            The enrollment who owns the facility.
     * @throws ServiceException
     */
    public void setFacilityReceivedFrom(String facility,
            EnrollmentDetermination enrollment) throws ServiceException;

    /**
     * Returns the person's enrollment.
     * 
     * @param person
     *            who contains the enrollment
     * @return the enrollment
     */
    public EnrollmentDetermination getEnrollmentDetermination(Person person);

    /**
     * Returns the veteran's purple heart decoration, if it exists.
     * 
     * @param person
     *            who contains the purple heart
     * @return the Purple Heart
     */
    public PurpleHeart getPurpleHeart(Person person);

    /**
     * Return the particular type of clinical determination from person.
     * 
     * @param classObject
     *            The type of clinical determination to return
     * @param person
     *            The person who contains the clinical determination
     * @return the clinical determination
     */
    public ClinicalDetermination getClinicalDetermination(Class classObject,
            Person person);

    /**
     * Set the rejection remark in a Purple Heart.
     * 
     * @param remark
     *            The remark to set.
     * @param purpleHeart
     *            The remark will be set on this purple heart.
     * @throws ServiceException
     */
    public void setRejectionRemark(String remark, PurpleHeart purpleHeart)
            throws ServiceException;

    /**
     * Return the particular type of SSN (Official,Other,Pesudo..)
     * 
     * @param code
     * @param person
     * @return
     */
    public SSN getSSN(String code, Person person) throws ServiceException;

    /**
     * Gets the current income test. If no income tests are defined or no income
     * test is considered current, null is returned.
     * 
     * @return The current income test or null.
     */
    public IncomeTest getCurrentIncomeTest(Person person);

    /**
     * Gets the current income test using additional criteria needed by
     * Determine Income Test Status for Eligibility Change.
     * 
     * @param person
     * @return
     */
    public IncomeTest getCurrentIncomeTestForEE(Person person);

    /**
     * Gets the latest income test. If no income tests are defined, null is
     * returned.
     * 
     * @return The latest income test or null.
     */
    public IncomeTest getLatestIncomeTest(Person person);

    /**
     * Lookup state by state code or state name. The state could be a state code
     * or a state name. Lookup the state by code first, if it is null, then
     * lookup by name.
     * 
     * @param stateNameOrCode
     * @return State
     * @throws BuilderException
     */
    public State getStateFromCodeOrName(String stateNameOrCode)
            throws ServiceException;

    /**
     * Both the ICN and the VPID are in the same format. The format is an ASTM
     * standard and is made up of the following items: 1. Sequence Number - A 16
     * character, number only field. 2. Delimiter - V 3. Check Digit - A six
     * character, number only field 4. Encoding Scheme - A six character, number
     * only field. To form the ICN or VPID, the sequence number, delimiter,
     * check digit and encoding scheme are concatenated together. ESR stores the
     * VPID value(in the Person table) in the long format i.e 1. The Sequence
     * number is prefixed with six leading zeros. 2. Delimiter 3. Check Digit 4.
     * The encoding scheme does not have to be populated, and if it is not, six
     * zeros are stored. If the first six characters of a VPID are zeros, and
     * the last six characters of a VPID or ICN are zeros, then the zeros can be
     * truncated to return the shortened VPID. e.g if VPID is
     * 0000001234567890V123456000000, the shortened format VPID/ICN is
     * 1234567890V123456.
     * 
     * @return ICN/Checksum after truncating the leading and trailing zeroes
     *         from the VPID value(shortened VPID)
     */
    public String getICNChecksum(String VPIDValue);

    /**
     * Sorts the PatientVisitSummary by last visit date from recent to old.
     * 
     * @param patientVisitSummaries
     * @return
     */
    public List sortLastVisitDateRecentToOld(Collection patientVisitSummaries);

    /**
     * If ESR has a HEC Period of Service (POS) then use it. If ESR does not
     * have a HEC POS and there is one sites POS then use the POS from this
     * single site. If ESR has more than one site POS and the POS for each site
     * is the same then use the POS from the site information. If ESR has more
     * than one site POS and the POS for each site is different then use the
     * most current POS based on this hierarchy: Persian Gulf War Vietnam Era
     * Korean World War II Merchant Marine World War I Spanish American
     * Post-Vietnam Era Post Korean Pre-Korean
     * 
     * @param person
     * @return ServicePeriod
     */
    public ServicePeriod getCurrentServicePeriod(MilitaryService militaryService);

    /**
     * Check if a code is of non-veteran eligibility code
     * 
     * @param code
     *            A code to check
     * @return true if equal. false otherwise
     */
    public boolean isNonVeteranEligibilityCode(String code);

    /**
     * Retrieve PersonTraits by VPID. Does NOT call PSIM API.
     * 
     * @param VPID
     * @return PersonTraits
     * @throws ServiceException
     */
    public PersonTraits getPersonTraitsByVPID(String VPID)
            throws ServiceException;
    
    public MilitaryServiceQueryStatus getMSDSQueryStatus(Person person) throws ServiceException;

    /**
     * Gets the current or future income test. If no income tests are defined or no income
     * test is considered current or future, null is returned.
     * 
     * @return The current or future income test or null.
     */
    public IncomeTest getCurrentOrFutureIncomeTest(Person person, Person pristinePerson);
    
    /**
     * CCR 11666 insert into SSA verification queue
     */
    
    public void addToSSNVerificationQueue(Person person) throws ServiceException;
    
    //CCR13142 to include VHIC Card Info
    /**
     * Retrieve VHIC Card ID by VPID. 
     * 
     * @param VPID
     * @return String
     * @throws ServiceException
     */
    public String getVhicIdByVPID(String VPID) throws ServiceException;

	public boolean isNonVeteranPrimaryEligibility(Person incoming);

	public String getPrimaryEligibilityCode(Person incoming);
    
    
    /**
     * Returns a person's eligibility status
     * 
     * @param person
     *            A person from which eligibility status is obtained
     * @return An eligibility status to which a person belongs
     * @throws ServiceException
     *             If failed to lookup an eligibility status
     */
    public EligibilityStatusPendVerfiReason getEligStatusPendingVerficationReason(Person person)
            throws ServiceException;
    /**
     * Sets the eligibility status Pending verification reason 
     *
     * @param code
     *            A process status code to set
     * @param person
     *            The person to which a process status belongs
     * @throws ServiceException
     *             If failed to lookup a process status
     */
    public void setEligStatusPendingVerficationReason(String code, Person person)
            throws ServiceException ;
    /**
     * Returns a person's eligibility status
     * 
     * @param person
     *            A person from which eligibility status is obtained
     * @return An eligibility status to which a person belongs
     * @throws ServiceException
     *             If failed to lookup an eligibility status
     */

    public void setEligStatusPendingVerfReasonExplain(String eligStatusPendingVerfReasonExplain, Person person)
            throws ServiceException;
    
    
}