

package gov.va.med.cds.hapi;


import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.parser.Parser;
import ca.uhn.hl7v2.util.Terser;
import gov.va.med.cds.exception.ErrorCodeEnum;
import gov.va.med.cds.hapi.extension.CustomPipeParser;
import gov.va.med.cds.hapi.extension.CustomUnformattedXmlParser;


public class HL7SupportHAPI
    extends
        AbstractHl7Support
{

    private static final String T_MESSAGE_TYPE = "/MSH-9";
    private static final String T_SURVEY_VERSION2 = "/TXA2-13-1";
    private static final String T_SURVEY_VERSION = "/TXA-13-1";
    
  
    private Message message;

    private Terser terser;


    /**
     * Constructor initializes new instance of translation support object with its message object.
     * 
     * @param message The message to be used by the support object.
     */
    protected HL7SupportHAPI( Message message )
    {
        this.message = message;
        this.terser = new Terser( message );
    }


    /**
     * Creates a new HL7 support object for the message.
     * 
     * @param message The HL7 message (ER7 or XML)
     * @return The HL7 support object.
     */
    public static HL7SupportInterface createTranslationSupport( String message )
    {
        if ( isEr7Encoded( message ) )
            return new HL7SupportHAPI( initEr7( message.replace( '\n', '\r' ) ) );
        else
            return new HL7SupportHAPI( initXml( message ) );
    }


    private static boolean isEr7Encoded( String message )
    {
        return ( message.startsWith( "MSH" ) ) || ( message.startsWith( "BHS" ) );
    }


    private static Message initEr7( String er7 )
    {
        try
        {
            // use the custom parser as thi
            Parser parser = new CustomPipeParser();
            //parser.setValidationContext( new ValidationContextImpl() );
            return parser.parse( er7 );

        }
        catch ( Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_PARSE_EXCEPTION, e );
        }
    }


    private static Message initXml( String xml )
    {
        try
        {
            return new CustomUnformattedXmlParser().parse( xml );
        }
        catch ( Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_PARSE_EXCEPTION, e );
        }
    }


    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.cds.hapi.IHL7Support#toEr7()
     */
    public String toEr7( )
    {
        try
        {
            return new CustomPipeParser().encode( this.message ).replace( '\n', '\r' );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_ENCODE_EXCEPTION, e );
        }
    }


    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.cds.hapi.IHL7Support#toXml()
     */
    public String toXml( )
    {
        try
        {
        	return new CustomUnformattedXmlParser().encode( this.message );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_ENCODE_EXCEPTION, e );
        }
    }


    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.cds.hapi.IHL7Support#getMessageData(java.lang.String)
     */
    public String getMessageData( String terserPath )
    {
        try
        {
            return this.terser.get( terserPath );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, terserPath );
        }
    }


    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.cds.hapi.IHL7Support#getSendingApplication()
     */
    public String getSendingApplication( )
    {
        String sendingApplication;
       
        try
        {
            sendingApplication = this.terser.get( T_SENDING_APPLICATION );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_SENDING_APPLICATION );
        }

        return processingHTHLogic( sendingApplication );
    }


    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.cds.hapi.IHL7Support#getMessageControlId()
     */
    public String getMessageControlId( )
    {
        try
        {
            return this.terser.get( T_MESSAGE_CONTROL_ID );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_MESSAGE_CONTROL_ID );
        }
    }


    public String getReceivingApplication( )
    {
        try
        {
            return this.terser.get( T_RECEIVING_APPLICATION );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_RECEIVING_APPLICATION );
        }
    }


    public String getReceivingFacilityStation( )
    {
        try
        {
            return (this.terser.get( T_RECEIVING_FACILITY_STATION ));
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_RECEIVING_FACILITY_STATION );
        }
    }
    
    public String getReceivingFacility( )
    {
        try
        {
            return this.terser.get( T_RECEIVING_FACILITY );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_RECEIVING_FACILITY );
        }
    }
    
    public String getReceivingFacilityType( )
    {
        try
        {
            return this.terser.get( T_RECEIVING_FACILITY_TYPE);
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_RECEIVING_FACILITY_TYPE );
        }
    }
    
    public String getFullReceivingFacility( )
    {
        try
        {
            return (this.terser.get( T_RECEIVING_FACILITY_STATION ) +"~"+ this.terser.get( T_RECEIVING_FACILITY ) +"~" + this.terser.get( T_RECEIVING_FACILITY_TYPE  ));
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_RECEIVING_FACILITY_STATION );
        }
    }

    public String getStationNumber( )
    {
        try
        {
            return this.terser.get( T_STATION_NUMBER );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_STATION_NUMBER );
        }
    }


    public String getSendingFacility( )
    {
        try
        {
            return this.terser.get( T_SENDING_FACILITY );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_SENDING_FACILITY );
        }
    }
    
    public String getSendingFacilityType( )
    {
        try
        {
            return this.terser.get( T_SENDING_FACILITY_TYPE );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_SENDING_FACILITY_TYPE );
        }
    }
    public String getFullSendingFacility( )
    {
        try
        {
            return (this.terser.get( T_FULL_SENDING_FACILITY )+"~"+ this.terser.get( T_SENDING_FACILITY ) +"~" + this.terser.get( T_SENDING_FACILITY_TYPE  ));
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_FULL_SENDING_FACILITY );
        }
    }

    public String getApplicationAcknowledgementType( )
    {
        try
        {
            return this.terser.get( T_APPLICATION_ACKNOWLEDGEMENT );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_APPLICATION_ACKNOWLEDGEMENT );
        }
    }


    public String getAcknowledgementCode( )
    {
        try
        {
            return this.terser.get( T_ACKNOWLEDGEMENT_CODE );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_ACKNOWLEDGEMENT_CODE );
        }
    }
    
    public String getAckOriginalMessageControlId()
    {
		try 
		{
			return this.terser.get( T_ACK_ORIGINAL_MSG_ID );
		} 
		catch (HL7Exception e) 
		{
			 throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_ACK_ORIGINAL_MSG_ID );
		}
    }


    public String getRequestWhatCode( )
    {
        String whatCode = null;
        String messageName = this.message.getName();

        if ( messageName.equals( "SPQ_Q08" ) )
        {
            String rawWhatCode = getMessageData( T_SPQ_Q08_WHAT_CODE );

            if ( rawWhatCode == null || rawWhatCode.length() == 0 )
            {
                throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, T_SPQ_Q08_WHAT_CODE );
            }

            whatCode = rawWhatCode.substring( 0, rawWhatCode.indexOf( ':' ) ).substring( 8 );
        }
        else if ( messageName.equals( "QRY_Q01" ) )
        {
            whatCode = getMessageData( T_QRY_Q01_WHAT_CODE );

            if ( whatCode == null || whatCode.length() == 0 )
            {
                throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, T_QRY_Q01_WHAT_CODE );
            }
        }
        else
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_WHAT_CODE_UNSUPPORTED );
        }

        return whatCode;
    }


    /**
     * 
     * 
     */
    public String getMessageUserId( )
    {
        String userId = null;
        String messageName = this.message.getName();

        if ( messageName.equals( "SPQ_Q08" ) )
        {
            userId = getMessageData( T_SPQ_Q04_USER_ID );

            if ( userId == null || userId.length() == 0 )
            {
                throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, T_SPQ_Q04_USER_ID );
            }

        }

        return userId;
    }


    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.cds.hapi.IHL7Support#getMessageType()
     */
    public String getMessageType( )
    {
        try
        {
            return this.terser.get( T_MESSAGE_TYPE );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_MESSAGE_TYPE );
        }
    }


    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.cds.hapi.IHL7Support#getMessageDate()
     */
    public String getMessageDateTime( )
    {
        try
        {
            return this.terser.get( T_MESSAGE_DATE_TIME );
        }
        catch ( HL7Exception e )
        {
            throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_MESSAGE_DATE_TIME );
        }
    }
    
    
    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.cds.hapi.IHL7Support#getSurveyVersion()
     */
    public String getSurveyVersion( )
    {
		try 
		{
			//return this.terser.get( T_SURVEY_VERSION );
			String surveyVersion = this.terser.get( T_SURVEY_VERSION );
			if(surveyVersion == null){
				surveyVersion = this.terser.get( T_SURVEY_VERSION2 );
			}
			return surveyVersion;
		} 
		catch (HL7Exception e) 
		{
			 throw new HL7SupportException( ErrorCodeEnum.HL7_SUPPORT_HAPI_TERSE_EXCEPTION, e, T_SURVEY_VERSION );
		}
    }
    
    
    

}
