/********************************************************************
 * Copyright © 2004 EDS. All rights reserved
 ********************************************************************/
//Package
package gov.va.med.esr.messaging.service.outbound;

// Java Classes

// Library Classes

// Framework Classes
import org.apache.commons.lang.ClassUtils;

import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.StopWatchLogger;
import gov.va.med.fw.util.builder.BuilderException;
import gov.va.med.fw.hl7.Message;
import gov.va.med.esr.common.model.messaging.MessageLogEntry;
import gov.va.med.esr.service.trigger.PersonTriggerEvent;
import gov.va.med.esr.service.MessagingService;

// Common Classes

// Messaging Classes

/**
 * Class to process outbound ACK (AA type).
 * 
 * @author Alex Yoon
 * @version 1.0
 */
public class ACKAAProcessService
    extends AbstractOutboundProcessService implements OutboundProcessService {

	private MessagingService messagingService = null;
	/**
     * Default constructor.
     */
    public ACKAAProcessService()
    {
        super();
    }

    public void processMessage(Object input) throws ServiceException
    {
    	if (input instanceof Object[])
    	{
    		//coming from OutboundMessageRouter with input as 
    		// Object[] {(Object)payload, (String) messageName, (CommonTriggerEvent) personTriggerEvent}
    		//VOA Ack FINAL status Message to MHV
    		Object[] args = (Object[])input;
    		if (args.length == 3 && args[2] instanceof PersonTriggerEvent)
    		{
    			java.util.List mleLst = this.getMessagingService().findVoaAaAckLogEntryByPersonId(
        				((PersonTriggerEvent) args[2]).getPersonId());
    			
    			if (mleLst != null && mleLst.size() > 0)
    			{
    				//only get the latest if exists
    				//NOTE: assuming no multiple submissions!!!
            		this.processMessage((MessageLogEntry)mleLst.get(0));
    			} 
    		}else
    		{
    			throw new ServiceException("Unknown input type: " + input.toString());
    		}
    		//
    	} else
    	{
    		this.processMessage((Message)input);
    	}
    }
    
    /**
     * Method to process the ACK message.
     * 
     * @param message
     */
    public void processMessage(Message message) throws ServiceException
    {
    	StopWatchLogger watch = null;     	
    	if(logger.isDebugEnabled())
    	{
	        watch = new StopWatchLogger( ClassUtils.getShortClassName( getClass() ) + " processMessage" );
	        watch.start();
    	}    	
        if(super.logger.isInfoEnabled())
        {
            super.logger.info("Building outbound AA ACK Message");
        } 

        try
        {
            Message ackMessage = super.buildMessage(new Object[] { message });

            super.publishMessage(ackMessage);
        }
        catch(BuilderException e)
        {
            throw new ServiceException(
                "Failed to build an ACK message due to an exception ", e);
        }finally{
        	if(logger.isDebugEnabled() && watch != null) {
        		watch.stopAndLog();
        	}
        }
    }
    
    /**
     * Method to process the VOA FINAL status ACK message.
     * 
     * @param message
     */
    private void processMessage(MessageLogEntry mle) throws ServiceException
    {
    	StopWatchLogger watch = null;     	
    	if(logger.isDebugEnabled())
    	{
	        watch = new StopWatchLogger( ClassUtils.getShortClassName( getClass() ) + " processMessage" );
	        watch.start();
    	}    	
        if(super.logger.isInfoEnabled())
        {
            super.logger.info("Building VOA FINAL status AA ACK Message");
        } 

    	//call AckBuilder
        try
        {
            Message ackMessage = super.buildMessage(new Object[] { mle });

            super.publishMessage(ackMessage);
        }
        catch(BuilderException e)
        {
            throw new ServiceException(
                "Failed to build a VOA FINAL status AA ACK message due to an exception ", e);
        }finally{
        	if(logger.isDebugEnabled() && watch != null) {
        		watch.stopAndLog();
        	}
        }
    
    	//update the log entry
        mle.setAckDate(new java.util.Date());
    	 super.logMessage(mle);
    	
    }

	public MessagingService getMessagingService() {
		return messagingService;
	}

	public void setMessagingService(MessagingService messagingService) {
		this.messagingService = messagingService;
	}
}