

package gov.va.med.cds.ejb;


import gov.va.med.cds.exception.ErrorCodeEnum;
import gov.va.med.cds.exception.RuntimeMDBOnMessageException;
import gov.va.med.cds.response.util.ResponseErrorSectionExtractor;
import gov.va.med.cds.util.MllpUtil;
import gov.va.med.mediator.client.messagemediator.MessageMediatorInterface;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import javax.interceptor.Interceptors;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor;
import org.springframework.jndi.JndiTemplate;

@Interceptors(SpringBeanAutowiringInterceptor.class)
public class CDSClinicalMdb implements MessageListener   
{

	protected final Log logger = LogFactory.getLog(getClass());
	
	@Autowired
	private MessageMediatorInterface messageMediator;
	@Autowired
    private ResponseErrorSectionExtractor responseErrorSectionExtractor;
	
    private Boolean defaultPersistOriginalMessage;

     public CDSClinicalMdb() {
   	}

     public void ejbCreate(){
    	 try{
    			defaultPersistOriginalMessage = ( Boolean )new JndiTemplate().lookup( "java:comp/env/ejb/mediator/defaultPersistOriginalMessage", Boolean.class );
    		}
    		catch ( Exception e )
         {
             logger.warn( String.format( "Error creating Clinical Message Driven Bean. " + "Could not identify processor. Error Reason: %s", e
                             .getMessage() ), e );
         }
     }
       

    /*
     * (non-Javadoc)
     * 
     * @see javax.jms.MessageListener#onMessage(javax.jms.Message)
     */
    public void onMessage( Message message )
    {
        String response;

        try
        {
            byte[] messageBytes = null;
            Boolean persistOriginal = message.propertyExists( MessageMediatorInterface.PROP_PERSIST_ORIGINAL ) ? message
                            .getBooleanProperty( MessageMediatorInterface.PROP_PERSIST_ORIGINAL ) : defaultPersistOriginalMessage;

            if ( message instanceof BytesMessage )
            {
                BytesMessage bytesMsg = ( BytesMessage )message;
                int msgLength = ( int )bytesMsg.getBodyLength();
                messageBytes = new byte[msgLength];
                bytesMsg.readBytes( messageBytes );
            }
            else if ( message instanceof TextMessage )
            {
                TextMessage textMsg = ( TextMessage )message;
                messageBytes = textMsg.getText().getBytes();
            }

            // remove non-printable characters from  the the message
            ByteBuffer messageBuffer = ByteBuffer.wrap( messageBytes );
            messageBuffer = MllpUtil.decode( new ByteBuffer[] { messageBuffer }, true, Charset.forName( "ISO-8859-1" ), Charset.defaultCharset() );

            response = messageMediator.processMessage( new String( messageBuffer.array() ), persistOriginal );

            responseErrorSectionExtractor.checkForErrorsInResponse( response );
        }
        catch ( JMSException jmsE )
        {
            String msg = jmsE.getMessage();
            logger.error( msg, jmsE );
            throw new RuntimeMDBOnMessageException( ErrorCodeEnum.MDB_ON_MESSAGE_JMS_EXCEPTION, jmsE, msg );
        }
    }


    public void setMessageMediator( MessageMediatorInterface messageMediator )
    {
        this.messageMediator = messageMediator;
    }


    public void setResponseErrorSectionExtractor( ResponseErrorSectionExtractor responseErrorSectionExtractor )
    {
        this.responseErrorSectionExtractor = responseErrorSectionExtractor;
    }
}
