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

// Java classes

// Library classes
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.exception.ExceptionUtils;

// Framework classes
import gov.va.med.fw.rule.RuleValidationException;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.validation.ValidationMessages;
import gov.va.med.fw.validation.ValidationServiceException;

// EDB classes
import gov.va.med.esr.common.clock.Clock.Type;
import gov.va.med.esr.common.model.ee.Application;
import gov.va.med.esr.common.model.ee.CancelDecline;
import gov.va.med.esr.common.model.ee.EGTSetting;
import gov.va.med.esr.common.model.ee.EnrollmentDetermination;
import gov.va.med.esr.common.model.ee.HealthBenefitProfile;
import gov.va.med.esr.common.model.ee.ReceivedEnrollment;
import gov.va.med.esr.common.model.ee.ServiceConnectionAward;
import gov.va.med.esr.common.model.ee.VerificationInfo;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.rule.data.EEInputData;
import gov.va.med.esr.common.rule.data.PersonInputData;
import gov.va.med.esr.common.rule.data.IneligibilityInputData;
import gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService;
import gov.va.med.esr.common.rule.service.FinancialInfoRuleService;
import gov.va.med.esr.common.rule.service.CommunicationRuleService;

/**
 * Project: Common
 *
 * @author DNS   LEV
 * @version 1.0
 */
public class EligibilityEnrollmentRuleServiceImpl extends
      AbstractRuleValidationServiceAwareImpl implements EligibilityEnrollmentRuleService {

   /**
    * An instance of serialVersionUID
    */
   private static final long serialVersionUID = 7635816577039685872L;

   private String eligibilityRuleParameters = null;

   private String enrollmentRuleParameters = null;

   private String ineligibilityRuleParameters = null;

   private String receivedEligibilityRuleParameters = null;

   private String otherEligibilityRuleParameters = null;

   private String personRuleParameters = null;

   private String handBookEventRuleParameters = null;

   //CCR12064
   private String healthBenefitProfileRuleParameters = null;

   private FinancialInfoRuleService financialInfoRuleService = null;

   private CommunicationRuleService communicationRuleService = null;

   /**
    *
    */
   public EligibilityEnrollmentRuleServiceImpl() {
      super();
   }

   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#processCancelDecline(gov.va.med.esr.common.model.ee.CancelDecline,
    *      gov.va.med.esr.common.model.person.Person)
    */
   public void processCancelDecline(CancelDecline incoming, Person onFile)
         throws ServiceException {
      Validate.notNull(onFile, "An onFile person must not be null ");
      //CCR12710
      if (logger.isDebugEnabled()) {
          logger.debug("EERuleServiceImpl processCD : incoming" + incoming + " onfile: " + onFile);
		}

      this.getMergeRuleService().mergeCancelDecline(incoming, onFile);
   }



   public void calculateEEForCleanup(Person onFile) throws ServiceException {
	   // Notice that we say NOT from UI
	   this.calculateEE(onFile, null, false, false, true, null, null, true);
   }

   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#calculateEEForExpireMTBatchJob(gov.va.med.esr.common.model.person.Person, java.lang.Integer)
    */
   public void calculateEEForExpireMTBatchJob(Person onFile, Integer incomeYear) throws ServiceException {
       this.calculateEE(onFile, incomeYear, false, false, true, null, null, false);
   }

    /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#calculateEE(gov.va.med.esr.common.model.person.Person,
    *      boolean, boolean)
    */
   public void calculateEE(Person onFile, boolean isDataFromGUI,
            boolean isReviewOnly) throws ServiceException {

	   //this.calculateEE(onFile, null, isDataFromGUI, isReviewOnly, null, null, false);
	   //this.calculateEE(onFile, null, isDataFromGUI, isReviewOnly, null, null, false);
       this.calculateEE(onFile, isDataFromGUI, isReviewOnly, null, null);
   }

   /**
     * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#calculateEE(gov.va.med.esr.common.model.person.Person, boolean, boolean, gov.va.med.esr.common.clock.Clock.Type)
     */
    public void calculateEE(Person onFile, boolean isDataFromGUI, boolean isReviewOnly, Type clockType, VAFacility sendingFacility) throws ServiceException {
        this.calculateEE(onFile, null, isDataFromGUI, isReviewOnly, true, clockType, sendingFacility, false);
    }

    public void calculateEE(Person onFile, boolean isDataFromGUI, boolean isReviewOnly, boolean shouldTriggerHBP, Type clockType, VAFacility sendingFacility) throws ServiceException {
        this.calculateEE(onFile, null, isDataFromGUI, isReviewOnly, shouldTriggerHBP, clockType, sendingFacility, false);
    }

    /**
     * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#calculateEE(gov.va.med.esr.common.model.person.Person,
     *      gov.va.med.esr.common.model.person.Person, boolean, boolean)
     */
   private void calculateEE(Person onFile, Integer incomeYear, boolean isDataFromGUI,
         boolean isReviewOnly, boolean shouldTriggerHBP, Type clockType, VAFacility sendingFacility, boolean cleanup) throws ServiceException {
      Person pristine = this.getPristinePerson(onFile);

      processServiceConnectedIndicator(onFile);

      Person incoming = (Person)onFile.clone();

      // Calculate eligibility codes

      EnrollmentDetermination result = this.doCalculateEligibility(incoming, onFile,
            pristine, isDataFromGUI, isReviewOnly,sendingFacility);

      // Adjust the income test status based on eligibility codes
      this.getFinancialInfoRuleService().determineIncomeTestFromElig(incoming, onFile,
            pristine, result, isDataFromGUI, sendingFacility);

      // Resync the incoming person since the financial flow updated the on file person.
      // This data
      // needs to be reflected in incoming person because of rule flow design.
      incoming = (Person)onFile.clone();

      // Calculate the enrollment priority and status
      this.doCalculateEnrollment(incoming, onFile, pristine, result, isDataFromGUI, isReviewOnly, cleanup);

      // Calculate Other codes
      this.doProcessOtherEligibililities(incoming, onFile, pristine, result,
            isDataFromGUI);

      EnrollmentDetermination current = onFile.getEnrollmentDetermination();
      if( current == null ) {
         current = new EnrollmentDetermination();
         onFile.setEnrollmentDetermination(current);
      }
      // Merge the results
      this.getMergeRuleService().mergeEnrollmentDetermination(result, current);
      onFile.setMigratedEE();

      if (shouldTriggerHBP) {
          //CCR 12877 Trigger HBP Rules, resync the incoming person again since enrollment had been determined and used by HBP ruleflow
          processHealthBenefitProfile((Person)onFile.clone(), onFile);
      }
      if (!isReviewOnly) {
          this.getCommunicationRuleService().triggerAutomaticLetters(onFile, incomeYear, isReviewOnly, clockType);
      }
   }

   /**
    * Method for use by batch EGT processing. Other callers should always use calcuteEE.
    *
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#determineEnrollment(gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.ee.EGTSetting)
    */
   public Person determineEnrollment(Person incoming, EGTSetting egtSetting)
         throws ServiceException {
      Validate.notNull(incoming, "An incoming person must not be null ");
      Person pristine = this.getPristinePerson(incoming);
      EnrollmentDetermination result = incoming.getEnrollmentDetermination();
      Validate.notNull(result, "A result enrollment must not be null ");

      //CCR12710
      if (logger.isDebugEnabled()) {
          logger.debug("EERuleServiceImpl detEnrollment : incoming: " + incoming);
      }

      // This will also trigger letter if needed. An enrollment determination should be
      // non-null since the veteran should be existing person.
      this.doCalculateEnrollment(incoming, incoming, pristine, result, false,
            false, egtSetting, false);

      // No merge necessary since we just update the person's current enrollment
      this.getCommunicationRuleService().triggerAutomaticLetters(incoming, null, false, null);
      return incoming;
   }

   /*
    * (non-Javadoc)
    *
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#determineEnrollmentNoTriggerLetters(gov.va.med.esr.common.model.person.Person)
    */
   public Person determineEnrollmentNoTriggerLetters(Person incoming)
           throws ServiceException {

       // validate incoming data
       Validate.notNull(incoming, "An incoming person must not be null ");

       // find the pristine person
       Person pristine = this.getPristinePerson(incoming);

       // get the incoming veteran?s enrollment determination
       EnrollmentDetermination result = incoming.getEnrollmentDetermination();
       Validate.notNull(result, "A result enrollment must not be null ");

       //CCR12710
       if (logger.isDebugEnabled()) {
           logger.debug("EERuleServiceImpl detEnrollmentNTL : incoming: " + incoming);
       }

       // apply enrollment rules
       this.doCalculateEnrollment(incoming, incoming, pristine, result, false,
               false, null, false);
       return incoming;
   }

   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#processIneligibility(gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.ee.VerificationInfo
    *       boolean isDataFromGUI)
    */
   public void processIneligibility(Person incoming, Person onFile,VAFacility sendingFacility,
         VerificationInfo verificationInfo,boolean isDataFromGUI) throws ServiceException {
	   //this.doProcessIneligibilityFactor(incoming, onFile, false, sendingFacility,verificationInfo);
       //CCR12710
	   if (logger.isDebugEnabled()) {
	          logger.debug("EERuleServiceImpl procIneligible : incoming: " + incoming + " onfile: " + onFile);
	      }
      this.doProcessIneligibilityFactor(incoming, onFile, isDataFromGUI, sendingFacility, verificationInfo);
   }



   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#manageIneligibility(gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.person.Person)
    */
   public void manageIneligibility(Person incoming, Person onFile)
         throws ServiceException {
      this.doProcessIneligibilityFactor(incoming, onFile, true, null,null);
   }


   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#manageReceivedEligibilities(gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.person.Person)
    */
   public void manageReceivedEligibilities(Person incoming, Person onFile)
         throws ServiceException {
      this.doProcessReceivedEligibilities(incoming, onFile, null, true);
   }

   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#processReceivedEligibilities(gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.person.Person)
    */
   public void processReceivedEligibilities(Person incoming, Person onFile, VerificationInfo verificationInfo,boolean isUpdateFromGUI)
         throws ServiceException {
      this.doProcessReceivedEligibilities(incoming, onFile, verificationInfo, isUpdateFromGUI);
   }


   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#processReceivedEnrollment(gov.va.med.esr.common.model.ee.ReceivedEnrollment,
    *      gov.va.med.esr.common.model.person.Person)
    */
   public void processReceivedEnrollment(ReceivedEnrollment incoming, Person onFile)
         throws ServiceException {
      Validate.notNull(onFile, "An onFile person must not be null ");

      if( incoming != null ) {
         Person pristine = this.getPristinePerson(onFile);
         ValidationMessages messages = this.getRuleValidationService()
               .validateReceivedEnrollment(incoming.getPerson(), onFile, pristine, false);

         if( messages != null && !messages.isEmpty() ) {
            throw new ValidationServiceException(messages);
         }

         ReceivedEnrollment receivedEnrollment = onFile.getReceivedEnrollment();
         if( receivedEnrollment == null ) {
            receivedEnrollment = new ReceivedEnrollment();
            onFile.setReceivedEnrollment(receivedEnrollment);
         }
         this.getMergeRuleService().mergeReceivedEnrollment(incoming, receivedEnrollment);
      }
      else {
         onFile.setReceivedEnrollment(null);
      }
   }

   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#processApplication(gov.va.med.esr.common.model.ee.Application,
    *      gov.va.med.esr.common.model.person.Person)
    */
   public void processApplication(Application incoming, Person onFile)
         throws ServiceException {
	   this.doProcessApplication(incoming, onFile, false);
   }

   public void manageApplication(Application application, Person onFile) throws ServiceException {
	   this.doProcessApplication(application, onFile, true);
   }



   /**
    * @param eligibilityRuleParameters
    *           The eligibilityRuleParameters to set.
    */
   public void setEligibilityRuleParameters(String eligibilityRuleParameters) {
      this.eligibilityRuleParameters = eligibilityRuleParameters;
   }

   /**
    * @param enrollmentRuleParameters
    *           The enrollmentRuleParameters to set.
    */
   public void setEnrollmentRuleParameters(String enrollmentRuleParameters) {
      this.enrollmentRuleParameters = enrollmentRuleParameters;
   }

   /**
    * @return Returns the handBookEventRuleParameters.
    */
   public String getHandBookEventRuleParameters() {
      return handBookEventRuleParameters;
   }

   /**
    * @param handBookEventRuleParameters
    *           The handBookEventRuleParameters to set.
    */
   public void setHandBookEventRuleParameters(String handBookEventRuleParameters) {
      this.handBookEventRuleParameters = handBookEventRuleParameters;
   }

   /**
    * @return Returns the eligibilityRuleParameters.
    */
   public String getEligibilityRuleParameters() {
      return eligibilityRuleParameters;
   }
   /**
    * @return Returns the enrollmentRuleParameters.
    */
   public String getEnrollmentRuleParameters() {
      return enrollmentRuleParameters;
   }

   /**
    * @return Returns the ineligibilityRuleParameters.
    */
   public String getIneligibilityRuleParameters() {
      return ineligibilityRuleParameters;
   }

   /**
    * @param ineligibilityRuleParameters
    *           The ineligibilityRuleParameters to set.
    */
   public void setIneligibilityRuleParameters(String ineligibilityRuleParameters) {
      this.ineligibilityRuleParameters = ineligibilityRuleParameters;
   }

   /**
    * @return Returns the receivedEligibilityRuleParameters.
    */
   public String getReceivedEligibilityRuleParameters() {
      return receivedEligibilityRuleParameters;
   }

   /**
    * @param receivedEligibilityRuleParameters
    *           The receivedEligibilityRuleParameters to set.
    */
   public void setReceivedEligibilityRuleParameters(
         String receivedEligibilityRuleParameters) {
      this.receivedEligibilityRuleParameters = receivedEligibilityRuleParameters;
   }

   /**
    * @return Returns the otherEligibilityRuleParameters.
    */
   public String getOtherEligibilityRuleParameters() {
      return otherEligibilityRuleParameters;
   }

   /**
    * @param otherEligibilityRuleParameters
    *           The otherEligibilityRuleParameters to set.
    */
   public void setOtherEligibilityRuleParameters(String otherEligibilityRuleParameters) {
      this.otherEligibilityRuleParameters = otherEligibilityRuleParameters;
   }

   /**
    * @return Returns the financialInfoRuleService.
    */
   public FinancialInfoRuleService getFinancialInfoRuleService() {
      return financialInfoRuleService;
   }

   /**
    * @param financialInfoRuleService
    *           The financialInfoRuleService to set.
    */
   public void setFinancialInfoRuleService(
         FinancialInfoRuleService financialInfoRuleService) {
      this.financialInfoRuleService = financialInfoRuleService;
   }

   /**
    * @return Returns the communicationRuleService.
    */
   public CommunicationRuleService getCommunicationRuleService() {
      return communicationRuleService;
   }

   /**
    * @param communicationRuleService
    *           The communicationRuleService to set.
    */
   public void setCommunicationRuleService(
         CommunicationRuleService communicationRuleService) {
      this.communicationRuleService = communicationRuleService;
   }

   public String getPersonRuleParameters() {
       return personRuleParameters;
   }

   public void setPersonRuleParameters(String personRuleParameters) {
       this.personRuleParameters = personRuleParameters;
   }

   private EnrollmentDetermination doCalculateEligibility(Person incoming, Person onFile,
           Person pristine, boolean isDataFromGUI, boolean isReviewOnly,VAFacility sendingFacility )
   throws ServiceException {
       Validate.notNull(incoming, "An incoming person must not be null ");
       Validate.notNull(onFile, "An on file person must not be null ");

       EnrollmentDetermination result = new EnrollmentDetermination();
       EEInputData data = new EEInputData(incoming, onFile, pristine, result,
               isDataFromGUI, isReviewOnly,sendingFacility );

       if (logger.isDebugEnabled()) {
	          logger.debug("EERuleServiceImpl doCalcElig : incoming: " + incoming + " onfile: " + onFile);
	      }

       this.invokeRuleFlow(this.getRuleParameters(this.getEligibilityRuleParameters()), data);

       return result;
   }

   private EnrollmentDetermination doCalculateEnrollment(Person incoming, Person onFile,
         Person pristine, EnrollmentDetermination result,
         boolean isDataFromGUI, boolean isReviewOnly, boolean cleanup) throws ServiceException {
      return this.doCalculateEnrollment(incoming, onFile, pristine, result,
            isDataFromGUI, isReviewOnly, null, cleanup);
   }

   private EnrollmentDetermination doCalculateEnrollment(Person incoming, Person onFile,
         Person pristine, EnrollmentDetermination result,
         boolean isDataFromGUI, boolean isReviewOnly, EGTSetting egtSetting, boolean cleanup)
         throws ServiceException {
      Validate.notNull(incoming, "An incoming person must not be null ");
      Validate.notNull(onFile, "An on file person must not be null ");
      Validate.notNull(result, "A result enrollment must not be null ");

      EEInputData data = new EEInputData(incoming, onFile, pristine, result,
            isDataFromGUI, isReviewOnly, null);
      // CCR 10311 and CCR 10023
      data.setCleanup(cleanup);
      data.setActiveEGTSetting(egtSetting);

      if (logger.isDebugEnabled()) {
          logger.debug("EERuleServiceImpl doCalcEnroll : incoming: " + incoming + " onfile: " + onFile);
      }

      this.invokeRuleFlow(this.getRuleParameters(getEnrollmentRuleParameters()), data);
      return result;
   }

   private Person doProcessIneligibilityFactor(Person incoming, Person onFile,
	         boolean isDataFromGUI, VAFacility sendingFacility, VerificationInfo verificationInfo)
	         throws ServiceException {
	      Validate.notNull(onFile, "An onFile person must not be null ");

	      // Only run this validation when from Messaging
	      if( !isDataFromGUI ) {
	         ValidationMessages messages = this.getRuleValidationService()
	               .validateIneligibility(incoming, isDataFromGUI);

	         if( messages != null && !messages.isEmpty() ) {
	            throw new ValidationServiceException(messages);
	         }
	      }

	      Person pristine = this.getPristinePerson(onFile);
	      IneligibilityInputData data = null;

	      if( verificationInfo != null ) {

	         data = new IneligibilityInputData(incoming, onFile, pristine, isDataFromGUI, sendingFacility,
	               verificationInfo);
	      }
	      else {
	         data = new IneligibilityInputData(incoming, onFile, pristine, sendingFacility,isDataFromGUI);
	      }

	      if (logger.isDebugEnabled()) {
	          logger.debug("EERuleServiceImpl doProcIneligible : incoming: " + incoming + " onfile: " + onFile);
	      }

	      this.invokeRuleFlow(this.getRuleParameters(this.getIneligibilityRuleParameters()),
	            data);

	      return onFile;
	   }


   private Person doProcessReceivedEligibilities(Person incoming, Person onFile, VerificationInfo verificationInfo,
         boolean isDataFromGUI) throws ServiceException {
      Validate.notNull(onFile, "An onFile person must not be null ");
      Validate.notNull(incoming, "A received eligibility must not be null ");

      Person pristine = this.getPristinePerson(onFile);

      EEInputData data = new EEInputData(incoming, onFile, pristine, isDataFromGUI);

      if(verificationInfo != null)
      {
    	  data.setMessageControlId(verificationInfo.getMessageControlId());
      }

      this.invokeRuleFlow(this.getRuleParameters(this
            .getReceivedEligibilityRuleParameters()), data);

      return onFile;
   }

   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#processOtherEligibilities(gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.ee.EnrollmentDetermination)
    */
   public void processOtherEligibililities(Person incoming, Person onFile,
         EnrollmentDetermination enrollment) throws ServiceException {
      Person pristine = this.getPristinePerson(onFile);
      this.doProcessOtherEligibililities(incoming, onFile, pristine, enrollment, false);
   }

   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#manageOtherEligibilities(gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.ee.EnrollmentDetermination)
    */
   public void manageOtherEligibilities(Person incoming, Person onFile,
         EnrollmentDetermination enrollment) throws ServiceException {
      Person pristine = this.getPristinePerson(onFile);
      this.doProcessOtherEligibililities(incoming, onFile, pristine, enrollment, true);
   }

   public void processServiceConnectedIndicator(Person person) {
       // Need to set Service Connection Indicator.
       // 3800 [UC12.7] Setting the Service Connected Indicator
       ServiceConnectionAward award = person.getServiceConnectionAward();
       if (award != null) {
           if (award.getRatedDisabilities().size() > 0 && award.getServiceConnectedPercentage() != null) {
               award.setServiceConnectedIndicator(Boolean.TRUE);
           }
           else {
               award.setServiceConnectedIndicator(Boolean.FALSE);
           }
       }
       else {
           award = new ServiceConnectionAward();
           award.setServiceConnectedIndicator(Boolean.FALSE);
           person.setServiceConnectionAward(award);
       }
   }

   public void processPerson(Person incoming, Person onFile, VAFacility sendingFacility, VerificationInfo verificationInfo, boolean updateFromGUI) throws ServiceException {
       Validate.notNull(onFile, "An onFile person must not be null ");
       Validate.notNull(incoming, "A incoming person must not be null ");

       Person pristine = this.getPristinePerson(onFile);

       PersonInputData data = new PersonInputData(incoming, onFile, pristine, sendingFacility, verificationInfo);
       data.setDataFromGUI(updateFromGUI);

       if (logger.isDebugEnabled()) {
	          logger.debug("EERuleServiceImpl processPerson : incoming: " + incoming + " onfile: " + onFile);
	   }

       this.invokeRuleFlow(this.getRuleParameters(this.getPersonRuleParameters()), data);
   }
   public void processPersonHandBookTrigger(Person incoming, Person onFile, VAFacility sendingFacility, VerificationInfo verificationInfo) throws ServiceException {
       Validate.notNull(onFile, "An onFile person must not be null ");
       Validate.notNull(incoming, "A incoming person must not be null ");

       Person pristine = this.getPristinePerson(onFile);

       PersonInputData data = new PersonInputData(incoming, onFile, pristine, sendingFacility, verificationInfo);
       data.setDataFromGUI(false);
       data.setHandBookTrigger(true);

       if (logger.isDebugEnabled()) {
	          logger.debug("EERuleServiceImpl procPersHBTrigger : incoming: " + incoming + " onfile: " + onFile);
	   }

       this.invokeRuleFlow(this.getRuleParameters(this.getPersonRuleParameters()), data);
   }
   /**
    * @param incoming
    * @param onFile
    * @param enrollment
    * @param isDataFromGUI
    * @throws ServiceException
    */
   private void doProcessOtherEligibililities(Person incoming, Person onFile,
         Person pristine, EnrollmentDetermination enrollment, boolean isDataFromGUI)
         throws ServiceException {

      Validate.notNull(incoming, "An incoming person must not be null ");
      Validate.notNull(onFile, "An on file person must not be null ");
      Validate.notNull(pristine, "A pristine person must not be null ");

      EEInputData data = new EEInputData(incoming, onFile, pristine, enrollment,
            isDataFromGUI, true, null);

      if (logger.isDebugEnabled()) {
          logger.debug("EERuleServiceImpl doProcOE : incoming: " + incoming + " onfile: " + onFile);
      }

      this.invokeRuleFlow(this
            .getRuleParameters(this.getOtherEligibilityRuleParameters()), data);
   }
   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#processOtherEligibilities(gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.ee.EnrollmentDetermination)
    */
   public void processHandBookTriggers(Person incoming, Person onFile, VAFacility sendingFacility, VerificationInfo verificationInfo) throws ServiceException {
      Person pristine = this.getPristinePerson(onFile);
      this.doProcessHandbookTriggers(incoming, onFile, pristine,  sendingFacility, verificationInfo);
   }
   /**
    * @param incoming
    * @param onFile
    * @param enrollment
    * @throws ServiceException
    */
   private void doProcessHandbookTriggers(Person incoming, Person onFile, Person pristine,
		   VAFacility sendingFacility, VerificationInfo verificationInfo) throws ServiceException {

      Validate.notNull(incoming, "An incoming person must not be null ");
      Validate.notNull(onFile, "An on file person must not be null ");
      Validate.notNull(pristine, "A pristine person must not be null ");

      PersonInputData data = new PersonInputData(incoming, onFile, pristine, sendingFacility, verificationInfo);
      //data.setDataFromGUI(isDataFromGUI);
      data.setHandBookTrigger(true);

      this.invokeRuleFlow(this
            .getRuleParameters(this.getHandBookEventRuleParameters()), data);
   }
   private void doProcessApplication(Application incoming, Person onFile, boolean isDataFromGUI) throws ServiceException {
	   Validate.notNull(onFile, "An onFile person must not be null ");
	   if (incoming != null) {
			Application application = onFile.getApplication();
			if (application == null) {
				application = new Application();
				onFile.setApplication(application);
			}

			if (isDataFromGUI) {
				Person person = incoming.getPerson();
				Person pristine = this.getPristinePerson(onFile);
				// Execute validations for application
				ValidationMessages messages = this.getRuleValidationService()
						.validateReceivedEnrollment(person, onFile, pristine,
								isDataFromGUI);

				if (messages != null && !messages.isEmpty()) {
					throw new ValidationServiceException(messages);
				}
			}

			this.getMergeRuleService().mergeApplication(incoming, application);
		} else {
			onFile.setApplication(null);
		}
   }

    public void processHealthBenefitProfile(Person incoming, Person onFile) throws ServiceException {
       this.doProcessHealthBenefitProfile(incoming, onFile, false);
   } // merge error

   private void doProcessHealthBenefitProfile(Person incoming, Person onFile, boolean isDataFromGUI) throws ServiceException {
      Validate.notNull(onFile, "A onFile Person must not be null ");
      Validate.notNull(incoming, "An incoming Person must not be null ");

      Person pristine = this.getPristinePerson(onFile);

      PersonInputData data = new PersonInputData(incoming, onFile, pristine, isDataFromGUI);

      this.invokeRuleFlow(this.getRuleParameters(this
            .getHealthBenefitProfileRuleParameters()), data);
   }

   /**
    * @see gov.va.med.esr.common.rule.service.EligibilityEnrollmentRuleService#manageHealthBenefitProfile(gov.va.med.esr.common.model.person.Person,
    *      gov.va.med.esr.common.model.person.Person)
    */
   public void manageHealthBenefitProfile(Person incoming, Person onFile)
         throws ServiceException {
      this.doProcessHealthBenefitProfile(incoming, onFile, true);
   }

		public String getHealthBenefitProfileRuleParameters() {
			return healthBenefitProfileRuleParameters;
		}

		public void setHealthBenefitProfileRuleParameters(
				String healthBenefitProfileRuleParameters) {
			this.healthBenefitProfileRuleParameters = healthBenefitProfileRuleParameters;
		}

}
