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

// Java classes
import java.util.Date;
import java.util.Iterator;
import java.util.Set;

// Library classes

// Framework classes
import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.rule.RuleDataAware;
import gov.va.med.fw.rule.RuleException;
import gov.va.med.fw.service.ServiceException;

// EDB classes
import gov.va.med.esr.common.rule.EGTInput;
import gov.va.med.esr.common.rule.data.EEInputData;
import gov.va.med.esr.common.rule.data.EgtInputData;
import gov.va.med.esr.common.model.ee.EGTProcessStatistic;
import gov.va.med.esr.common.model.ee.EnrollmentDetermination;
import gov.va.med.esr.common.model.ee.EGTSetting;
import gov.va.med.esr.common.model.lookup.EnrollmentPrioritySubGroup;


/**
 * Project: Common
 * @author DNS   LEV
 * @version 1.0
 */
public class EGTParameter extends BaseParameter implements EGTInput {

    private static final long serialVersionUID = 5599678794687343432L;
    
    
    public boolean isNewEGTSetting() {
        EGTSetting egtSetting = getEGTSetting();
        return (egtSetting != null && egtSetting.getEntityKey() != null) ? false : true;
    }

    public String getEGTType() throws RuleException {
        EGTSetting egtSetting = getEGTSetting();
        return (egtSetting != null && egtSetting.getType() != null) ? egtSetting.getType().getCode() : null;
    }

    /* 
     * @see gov.va.med.esr.common.rule.EGTInput#getEGTPriorityGroup()
     */
    public String getEGTPriorityGroup() throws RuleException {
        EGTSetting egtSetting = getEGTSetting();
        return (egtSetting != null && egtSetting.getPriorityGroup() != null) ? egtSetting.getPriorityGroup().getCode() : null;
    }
    
    /*
     * @see gov.va.med.esr.common.rule.EGTInput#getEGTEffectiveDate()
     */
    public Date getEGTEffectiveDate() throws RuleException {
        EGTSetting egtSetting = getEGTSetting();
        return (egtSetting != null) ? egtSetting.getEffectiveDate() : null;
    }

    /*
     * @see gov.va.med.esr.common.rule.EGTInput#isRetroactiveFurureEGTSettingExists()
     */
    public boolean isRetroactiveFurureEGTSettingExists() throws RuleException {
        boolean flag = false;
        try {
            EGTSetting egtSetting = getEGTSetting();
            EntityKey egtSettingKey = egtSetting.getEntityKey();
            Set futureEGTs = this.getEgtService().getFutureEGTSettings();
            if(futureEGTs != null && !futureEGTs.isEmpty()) {
                Date currentDate = this.getCurrentDate();
                for(Iterator iter=futureEGTs.iterator(); iter.hasNext();) {
                    EGTSetting egt = (EGTSetting)iter.next();
                    // If the incoming EGT is being updated skip it 
                    if( egt == null || (egtSettingKey != null && egtSettingKey.equals(egt.getEntityKey())) ) {
                        continue;
                    }
                    // If the Process EGT start is null and effective date is in the past
                    if(this.getProcessEGTStartDate(egt) == null && !this.isAfter(egt.getEffectiveDate(),currentDate)) {
                        flag = true;
                        break;
                    }

                }
            }
        } catch(Exception ex) {
            throw new RuleException("Error while getting the future retroactive EGT counts",ex);
        }
        return flag;
    }

    public void setEnrollmentSubPriority(String subGroup) throws RuleException {
        try {
            EGTSetting egtSetting = getResultEGTSetting();
            EnrollmentPrioritySubGroup enrollmentPrioritySubGroup = (EnrollmentPrioritySubGroup)this.getLookupService().getByCode(EnrollmentPrioritySubGroup.class,subGroup);
            egtSetting.setPrioritySubGroup(enrollmentPrioritySubGroup);
        } catch(Exception ex) {
            throw new RuleException("Error while setting the enrollment sub priority",ex);
        }
    }
    
    /**
     * @see gov.va.med.esr.common.rule.parameter.EGTInput#getCurrentEGTEffectiveDate()
     */
    public Date getCurrentEGTEffectiveDate() throws RuleException {
        EGTSetting es = this.getCurrentEGTSetting();        
        return es != null ? es.getEffectiveDate() : null;
    }

    /**
     * @see gov.va.med.esr.common.rule.EGTInput#isCalcEnrPriorityGreaterThanEGT()
     */
    public boolean isCalcEnrPriorityGreaterThanEGT() throws RuleException {
        try {
            String egtPriority = getCurrentEGTPriorityGroup();
            String priority = this.getCalculatedPriorityCode();
            if (priority == null || egtPriority == null) {
                return false;
            }
            return priority.compareTo(egtPriority) > 0;
        }
        catch (ServiceException e) {
            throw new RuleException("Failed to get EGT priority", e);
        }     
    }

    /**
     * @see gov.va.med.esr.common.rule.EGTInput#isCalcEnrPriorityLessThanEGT()
     */
    public boolean isCalcEnrPriorityLessThanEGT() throws RuleException {
        try {
            String egtPriority = getCurrentEGTPriorityGroup();
            String priority = this.getCalculatedPriorityCode();
            if (priority == null || egtPriority == null) {
                return false;
            }
            return priority.compareTo(egtPriority) < 0;
        }
        catch (ServiceException e) {
            throw new RuleException("Failed to get EGT priority", e);
        }      
    }

    /**
     * @see gov.va.med.esr.common.rule.EGTInput#isCurrentEGTPriorityLessThan(java.lang.String)
     */
    public boolean isCurrentEGTPriorityLessThan(String priority) throws RuleException {
        String egtPriority = getCurrentEGTPriorityGroup();
        // TODO - not going to reject if a priority is null. Discuss with David.
        return (priority != null && egtPriority != null) ? egtPriority.compareTo(priority) < 0 : false;
    }

    public String getCurrentEGTPriorityGroup() throws RuleException {
        EGTSetting currentEGTSetting = this.getCurrentEGTSetting();
        return (currentEGTSetting != null && currentEGTSetting.getPriorityGroup() != null) ? currentEGTSetting.getPriorityGroup().getCode() : null;
    }
    
    public String getCurrentEGTPrioritySubGroup() throws RuleException {
        EGTSetting currentEGTSetting = this.getCurrentEGTSetting();
        return (currentEGTSetting != null && currentEGTSetting.getPrioritySubGroup() != null) ? currentEGTSetting.getPrioritySubGroup().getCode() : null;
    }
    
    public Date getProcessEGTStartDate(){
        return this.getProcessEGTStartDate(this.getEGTSetting());
    }
    
    public Date getPristineEGTEffectiveDate(){
        return null;
    }
    
    public Date getEGTEffectiveStartDate(){
        return null;
    }
    
	/**
	 * @see gov.va.med.esr.common.rule.EGTInput#setEGTProcessStatus(java.lang.String)
	 */
	public void setEGTProcessStatus(String status) {
	    // TODO Auto-generated method stub
	    
	}
    
	/**
	 * @see gov.va.med.esr.common.rule.EGTInput#startEGTProcess()
	 */
	public void startEGTProcess() {
		// TODO Auto-generated method stub

	}
    
    /**
     * @see gov.va.med.esr.common.rule.EGTInput#isRequestToTerminateEGTProcess()
     */
    public boolean isRequestToTerminateEGTProcess() {
        // TODO Auto-generated method stub
        return false;
    }
    
    /**
     * @see gov.va.med.esr.common.rule.EGTInput#terminateEGTProcess()
     */
    public void terminateEGTProcess() {
        // TODO Auto-generated method stub

    }
    
    /**
     * @see gov.va.med.esr.common.rule.EGTInput#updateEGTRecord()
     */
    public void updateEGTRecord() throws RuleException {
        try {
            this.getMergeRuleService().mergeEGTSetting(this.getEGTSetting(),this.getResultEGTSetting());
        } catch(Exception ex) {
            throw new RuleException("Error while updating the EGT settings",ex);
        }
    }    
    
    
    // ******************************** Private methods ******************************** //
    
    private String getCalculatedPriorityCode() throws ServiceException {
        EnrollmentDetermination ed = null;
        if (this.getRuleDataAware() instanceof EEInputData) {
            // Assumes result not linked to person
            ed = ((EEInputData)this.getRuleDataAware()).getResultEnrollmentDetermination();
        } else {
            // Assumes result linked to person
            ed = this.getResultPerson() != null ? this.getHelperService().getEnrollmentDetermination(this.getResultPerson()) : null;
        }
        return (ed != null && ed.getPriorityGroup() != null) ? ed.getPriorityGroup().getCode() : null;
   }
    
    
    private Date getProcessEGTStartDate(EGTSetting egtSetting){
        EGTProcessStatistic processStatistic = (egtSetting != null) ? egtSetting.getProcessStatistic() : null;
        return (processStatistic != null) ? processStatistic.getProcessStartDate() : null;
    }
    

    private EGTSetting getEGTSetting() {
        return (this.getEgtInputData() != null) ? this.getEgtInputData().getIncomingEGTSetting() : null;
    }
    
    private EGTSetting getResultEGTSetting() {
        return (this.getEgtInputData() != null) ? this.getEgtInputData().getResultEGTSetting() : null;
    }
    
    private EgtInputData getEgtInputData() {
        RuleDataAware ruleDataAware = this.getRuleDataAware();
        return (ruleDataAware instanceof EgtInputData) ? (EgtInputData) ruleDataAware : null;     
    }
}
