/**
 * 
 */


package gov.va.med.cds.hapi;


import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import gov.va.med.cds.exception.ErrorCodeEnum;
import gov.va.med.hds.hdr.hl7.parser.HL7MessageParser;
import gov.va.med.hds.hdr.hl7.parser.HL7MessageParserEvent;
import gov.va.med.hds.hdr.hl7.parser.HL7MessageParserListener;


/**
 * @author vhaislegberb
 *
 */
public class Hl7SupportHdrLegacy
    extends
        AbstractHl7Support
    implements
        HL7MessageParserListener
{
    private static final String T_MESSAGE_TYPE = "/MSH-9-1";
    private static final String T_SURVEY_VERSION = "/TXA-13-1";
    
    private static final List<String> SUPPORTED_MESSAGE_DATA = Arrays.asList( T_ACKNOWLEDGEMENT_CODE, T_APPLICATION_ACKNOWLEDGEMENT,
                    T_MESSAGE_CONTROL_ID, T_MESSAGE_DATE_TIME, T_MESSAGE_TYPE, T_QRY_Q01_WHAT_CODE, T_RECEIVING_APPLICATION, T_RECEIVING_FACILITY,
                    T_SENDING_APPLICATION, T_SENDING_FACILITY, T_SPQ_Q04_USER_ID, T_SPQ_Q08_WHAT_CODE, T_STATION_NUMBER, T_SURVEY_VERSION );

    private String message;

    private Map<String, String> messageDataMap = new HashMap<String, String>();


    /**
     * Public constructor for creating a new Legacy HDR HL7 Support object.
     * @param hl7Er7Message The er7 encoded HL7 message to use as the basis for the support.
     * @throws HL7SupportException
     */
    public Hl7SupportHdrLegacy( String hl7Er7Message )
        throws HL7SupportException
    {
        this.message = hl7Er7Message;

        try
        {
            HL7MessageParser parser = new HL7MessageParser( this.message );
            parser.addParserEventListener( this );
            parser.parseMessage();
        }
        catch ( Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_PARSE_EXCEPTION, e );
        }
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getAcknowledgementCode()
     */
    @Override
    public String getAcknowledgementCode( )
    {
        return getMessageData( T_ACKNOWLEDGEMENT_CODE );
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getApplicationAcknowledgementType()
     */
    @Override
    public String getApplicationAcknowledgementType( )
    {
        return getMessageData( T_APPLICATION_ACKNOWLEDGEMENT );
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getMessageControlId()
     */
    @Override
    public String getMessageControlId( )
    {
        return getMessageData( T_MESSAGE_CONTROL_ID );
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getMessageData(java.lang.String)
     */
    @Override
    public String getMessageData( String terserPath )
    {
        String data = this.messageDataMap.get( terserPath );
        if ( data == null )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, terserPath );
        }

        return data;
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getMessageDateTime()
     */
    @Override
    public String getMessageDateTime( )
    {
        return getMessageData( T_MESSAGE_DATE_TIME );
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getMessageType()
     */
    @Override
    public String getMessageType( )
    {
        return getMessageData( T_MESSAGE_TYPE );
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getMessageUserId()
     */
    @Override
    public String getMessageUserId( )
    {
        return getMessageData( T_SPQ_Q04_USER_ID );
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getReceivingApplication()
     */
    
    public String getReceivingApplication( )
    {
        return getMessageData( T_RECEIVING_APPLICATION );
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getReceivingFacility()
     */
    @Override
    public String getReceivingFacility( )
    {
        return getMessageData( T_RECEIVING_FACILITY );
    }
    public String getReceivingFacilityStation( )
    {
        return getMessageData( T_RECEIVING_FACILITY_STATION );
    }
    public String getReceivingFacilityType( )
    {
        return getMessageData( T_RECEIVING_FACILITY_TYPE );
    }
    public String getFullReceivingFacility( )
    {
        return getMessageData(T_RECEIVING_FACILITY_STATION);
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getRequestWhatCode()
     */
    @Override
    public String getRequestWhatCode( )
    {
        return getMessageData( T_QRY_Q01_WHAT_CODE );
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getSendingApplication()
     */
    @Override
    public String getSendingApplication( )
    {
       String sendingApplication = getMessageData( T_SENDING_APPLICATION );
        
       return processingHTHLogic(sendingApplication); 
    }
    
    
    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getSurveyVersion()
     */
    @Override
    public String getSurveyVersion( )
    {
    	return getMessageData( T_SURVEY_VERSION );
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getSendingFacility()
     */
    @Override
    public String getSendingFacility( )
    {
        return getMessageData( T_SENDING_FACILITY );
    }
    public String getSendingFacilityType( )
    {
        return getMessageData( T_SENDING_FACILITY_TYPE );
    }
    public String getFullSendingFacility( )
    {
        return getMessageData( T_FULL_SENDING_FACILITY );
    }

    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#getStationNumber()
     */
    @Override
    public String getStationNumber( )
    {
        return getMessageData( T_STATION_NUMBER );
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#toEr7()
     */
    @Override
    public String toEr7( )
    {
        return this.message;
    }
    
    public String getAckOriginalMessageControlId()
    {
		
		return getMessageData( T_ACK_ORIGINAL_MSG_ID );
		
    }


    /* (non-Javadoc)
     * @see gov.va.med.cds.hapi.HL7SupportInterface#toXml()
     */
    @Override
    public String toXml( )
    {
        throw new UnsupportedOperationException(
                        "The HL7SupportHdrLegacy object does not support converting the ER7 encoded HL7 message into XML encoded HL7." );
    }


    @Override
    public void beginComponent( HL7MessageParserEvent arg0 )
    {
    }


    @Override
    public void beginField( HL7MessageParserEvent arg0 )
    {
    }


    @Override
    public void beginSegment( HL7MessageParserEvent arg0 )
    {
    }


    @Override
    public void beginSubcomponent( HL7MessageParserEvent arg0 )
    {
    }


    @Override
    public void endComponent( HL7MessageParserEvent event )
    {
        // Terser Path should look like '/SEG-F-C'
        String terserString = String.format( "/%s-%d-%d", event.getSegmentName(), event.getFieldIndex(), event.getComponentIndex() );
//        if ( isSupported( terserString ) )
//        {
            this.messageDataMap.put( terserString, event.getText() );
//            System.out.println( "terserString: " + terserString + ", tsxt: " + event.getText() );
//        }
    }


    @Override
    public void endField( HL7MessageParserEvent event )
    {
        // Terser Path should look like '/SEG-F'
        String terserString = String.format( "/%s-%d", event.getSegmentName(), event.getFieldIndex() );
        if ( isSupported( terserString ) )
        {
            this.messageDataMap.put( terserString, event.getText() );
        }
    }


    @Override
    public void endSegment( HL7MessageParserEvent event )
    {
    }


    @Override
    public void endSubcomponent( HL7MessageParserEvent event )
    {
        // Terser Path should look like '/SEG-F-C-S'
        String terserString = String.format( "/%s-%d-%d-%d", event.getSegmentName(), event.getFieldIndex(), event.getComponentIndex(), event
                        .getSubcomponentIndex() );
        if ( isSupported( terserString ) )
        {
            this.messageDataMap.put( terserString, event.getText() );
        }

    }


    @Override
    public void repeatField( HL7MessageParserEvent event )
    {
    }
    
    
    /**
     * Determines whether the terser path is supported by the parser.
     * @param terserPath The terser path in question.
     * @return Returns true if the path is supported; otherwise false.
     */
    private boolean isSupported( String terserPath )
    {
        return (terserPath.startsWith( "/MSH" ) || SUPPORTED_MESSAGE_DATA.contains( terserPath ));
    }

}
