

package gov.va.med.cds.socket.server.handler;


import gov.va.med.cds.hapi.HL7SupportException;
import gov.va.med.cds.hapi.HL7SupportInterface;
import gov.va.med.cds.hapi.HL7Utility;
import gov.va.med.mediator.client.messagemediator.JmsMessageMediatorDelegate;


public class SimpleVistACommitAckResponseGenerator
    extends
        AbstractResponseGenerator
{
    private static final String ACK_MESSAGE = "MSH^~|\\&^%s^200HD~HDR.MED.DNS   ~DNS^%s^%s~%s~DNS^%s^^ACK^%s^P^2.4\rMSA^%s^%s^%s";
    final static String COMMIT_ACK = "CA";
    final static String COMMIT_ERROR = "CE";
    final static String COMMIT_REJECT = "CR";

    private String getMessageData( HL7SupportInterface hl7Support, String terserPath, String defaultValue )
    {
        String messageData = defaultValue;

        if ( hl7Support != null )
        {
            try
            {
                messageData = hl7Support.getMessageData( terserPath );
            }
            catch ( Exception ex )
            {
                /* Swallow the exception */
            }
        }

        return messageData;
    }


    /*
     * (non-Javadoc)
     * @see gov.va.med.cds.socket.server.handler.ResponseGeneratorInterface#createResponse(gov.va.med.cds.hapi.HL7SupportInterface, java.lang.String, java.lang.Exception)
     */
    public String createResponse( HL7SupportInterface requestHl7Support, String response, String responseMessageControlId, Exception exception )
    {

        // Try to initialize the response fields
        String sendingApplication = getMessageData( requestHl7Support, "/MSH-3", "ERROR" );
        String sendingFacility = getMessageData( requestHl7Support, "/MSH-4-1", "ERROR" );
        String sendingFacilityName = getMessageData( requestHl7Support, "/MSH-4-2", "ERROR" );
        String receivingApplication = getMessageData( requestHl7Support, "/MSH-5", "ERROR" );
        String messageControlId = getMessageData( requestHl7Support, "/MSH-10", "ERROR" );
        String responseMessageDateTime = createMessageDateTime();

        String errorText = "";
        
        if ( exception != null )
        {
            errorText = getErrorText( exception );
        }
        else if ( response != null && response.startsWith( "<" + JmsMessageMediatorDelegate.ERROR_SECTION ) )
        {
            errorText = ( stripErrorSection( response ) );
        }

        return String.format( ACK_MESSAGE, receivingApplication, sendingApplication, sendingFacility, sendingFacilityName,
                        responseMessageDateTime, responseMessageControlId, getAckType( exception, response ), messageControlId, errorText );

    }

    /**
     * Removes error section tags form error message to form an error text from it for the Ack.
     * @param response
     * @return
     */
    protected String stripErrorSection( String response )
    {
        if ( response == null || response.equals( JmsMessageMediatorDelegate.SUCCESS ) )
            return "";

        // skip <errorSection> at the beginning
        int front = JmsMessageMediatorDelegate.ERROR_SECTION.length() + 2;

        // skip </errorSection> at the end
        int back = JmsMessageMediatorDelegate.ERROR_SECTION.length() + 3;

        String errorText = response.substring( front, response.length() - back );
        return trimLengthToEighty( errorText );
    }


    private String getAckType( Exception e, String response )
    {
        if ( e == null && response == JmsMessageMediatorDelegate.SUCCESS )
        {
            return COMMIT_ACK;
        }
        else
        {
            if ( e instanceof HL7SupportException || e instanceof AccessValidatorException )
            {
                return COMMIT_REJECT;
            }
            else
            {
                return COMMIT_ERROR;
            }
        }
    }


    String createMessageDateTime( )
    {
        return HL7Utility.createMessageDateTime();
    }

}