/*******************************************************************************
 * Copyright © 2004-2005 EDS. All rights reserved
 ******************************************************************************/
package gov.va.med.esr.service.impl;

// Java Classes

import java.io.Serializable;

import org.apache.commons.lang.Validate;


import gov.va.med.fw.hl7.InvalidMessageException;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.StringUtils;
import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.lookup.FunctionalGroup;
import gov.va.med.esr.common.model.lookup.WkfCaseType;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.PersonLockedReason;
import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKey;
import gov.va.med.esr.common.model.person.id.VPIDEntityKey;
import gov.va.med.esr.common.model.workload.WorkflowCaseInfo;
import gov.va.med.esr.service.PersonIdentityTraits;
import gov.va.med.esr.service.GenerateQRYZ11MessagingService;
import gov.va.med.esr.service.UnknownLookupCodeException;
import gov.va.med.esr.service.UnknownLookupTypeException;
import gov.va.med.esr.service.WorkflowService;
import gov.va.med.esr.service.trigger.MessageCaseTriggerEvent;
import gov.va.med.esr.service.trigger.PersonTriggerEvent;
import gov.va.med.esr.service.trigger.PersonTrigger;

/**
 * Created to generate QRY-Z11 messages for temporary batch process.
 * 
 * Created Aug 18, 2008 3:14:36 PM
 * @author DNS   GALLAS
 */
public class GenerateQRYZ11MessagingServiceImpl extends MessagingServiceImpl implements GenerateQRYZ11MessagingService {
      
    /**
     * An instance of serialVersionUID
     */
    private static final long serialVersionUID = -4077153102997010638L;

    private WorkflowService workflowService = null;

    /**
    * A default constructor
    */
   public GenerateQRYZ11MessagingServiceImpl() {
      super();
   }

   public void generateMessage(PersonEntityKey key, String VPID) throws ServiceException {
       VPIDEntityKey entityKey = 
           CommonEntityKeyFactory.createVPIDEntityKey(VPID);
       PersonIdentityTraits identityTraits = getPsDelegateService().getIdentityTraits(entityKey);
     
       generateQRYZ11(key, identityTraits);
   }
   
   private void generateQRYZ11(PersonEntityKey key, PersonIdentityTraits identityTraits) throws ServiceException {
       if(logger.isDebugEnabled())
           logger.debug("GenerateQRYZ11MessagingServiceImpl.generateQRYZ11(): Generate QRY-Z11 for person " + key.getKeyValueAsString());

       Validate.notNull(key, "PersonEntityKey must not be null");
       Validate.notNull(identityTraits, "Identity Traits must not be null");
        
       PersonTriggerEvent personTriggerEvent = new PersonTriggerEvent(PersonTrigger.DestinationType.MESSAGING,
                PersonTrigger.TargetType.VBA, PersonTrigger.DispatchType.QUERY,  PersonTrigger.DataType.ELIGIBILITY);
       personTriggerEvent.setPersonId(key);
       personTriggerEvent.setIdentityTraits(identityTraits);

       // Trigger QRYZ11
       getTriggerRouter().processTriggerEvent(personTriggerEvent);
    }
   
   public void generateMessageForPendingTraitsClock(Person person) throws ServiceException {
	   
	   // Before we allow processing to continue, we need to make sure
       // there is no "pending" updates to identity traits for this person. if it is still pending,
       // something is wrong with the traits update process since we already waited for the clock to expire.
       if( person.isPersonLocked()
             && ( PersonLockedReason.PENDING_IDENTITY_TRAIT_UPDATES.getReason()
                   .equals(person.getPersonLockedReason().getReason()) ) ) 
       {
    	   // Create a DQ Workload case, log error
 		  String errMsg = "VBA message not processed due to Pending Identity Traits, QRY~Z11 cannot be sent. vpid= " + person.getVPIDValue();
		
 		  createWorkloadCase(FunctionalGroup.DQ.getCode(), 
				WkfCaseType.CODE_REVIEW_FILE.getCode(), null,
				errMsg, person.getPersonEntityKey());

 		  logger.error(errMsg);
       }
       else {
    	   generateMessage(person.getPersonEntityKey(), person.getVPIDValue());
       }
   }
   
   private void createWorkloadCase(String groupType, String caseType, String issueType,
	         String description, PersonEntityKey key) throws ServiceException {
	      Validate.notNull(groupType, "A Group type must not be null");
	      Validate.notNull(caseType, "A case type must not be null");

	      // Create a regular case if message info is not available
	       WorkflowCaseInfo caseInfo = new WorkflowCaseInfo();
	       
	       caseInfo.setPersonEntityKey(key);

	      try {
	         caseInfo.setErrorMessage(description);
	         caseInfo.setGroupType(this.getLookupService()
	               .getFunctionalGroupByCode(groupType));
	         caseInfo.setCaseType(this.getLookupService().getWkfCaseTypeByCode(caseType));
	         if( StringUtils.isNotEmpty(issueType) ) {
	            caseInfo.setIssueType(this.getLookupService()
	                  .getWkfIssueTypeByCode(issueType));
	         }
	         getWorkflowService().autoCreateCase(caseInfo);

	      }
	      catch( Exception e ) {
	         if( this.logger.isDebugEnabled() ) {
	            logger.debug("Case description: " + description);
	            logger.debug("Case type: " + caseType);
	            logger.debug("Failed to create case due to ", e);
	         }
	         throw new ServiceException ("Failed to create a case", e);
	      }
	   }

 	public WorkflowService getWorkflowService() {
		return workflowService;
	}

	public void setWorkflowService(WorkflowService workflowService) {
		this.workflowService = workflowService;
	}
}