

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


import gov.va.med.cds.util.MllpUtil;
import gov.va.med.cds.util.StreamUtil;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;


public class MultiThreadedClientConnector
    extends
        Thread

{

    private static Log LOGGER = LogFactory.getLog( MultiThreadedClientConnector.class );

    private static final String PORT = "5002";

    private static final String LBPORT = "6031";

    private static ResourceLoader loader = new DefaultResourceLoader();


    @Override
    public void run( )
    {
        LOGGER.info( "Starting : " + Thread.currentThread().getId() );

        try
        {
            connectToServer();
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }
        catch ( InterruptedException e )
        {
            e.printStackTrace();
        }

        LOGGER.info( "Ending : " + Thread.currentThread().getId() );
    }


    private IoBuffer getMessage( )
        throws IOException
    {
        String hl7Er7Message = null;

        Resource resource = loader.getResource( "classpath:gov/va/med/cds/socket/server/rx_002.er7" );

        hl7Er7Message = StreamUtil.streamToString( resource.getInputStream() );

        ByteBuffer buffer = encodeToMllp( hl7Er7Message );

        IoBuffer messageIoBuffer = IoBuffer.allocate( buffer.limit() );

        int index = 0;

        while ( buffer.hasRemaining() && ( index < buffer.limit() ) )
        {
            messageIoBuffer.put( index, buffer.get( index ) );

            index++ ;
        }

        return messageIoBuffer;
    }


    private ByteBuffer encodeToMllp( String hl7Er7Message )
    {
        ByteBuffer buffer = ByteBuffer.allocate( hl7Er7Message.toString().getBytes().length );

        buffer.put( hl7Er7Message.toString().getBytes() );

        return MllpUtil.encode( buffer, Charset.forName( "ISO-8859-1" ), Charset.defaultCharset() );
    }


    private String getHl7er7( )
    {

        String hl7er7Record = null;

        BufferedReader bufferedReader = null;

        StringBuilder record = new StringBuilder();

        try
        {
            bufferedReader = new BufferedReader( new FileReader( "src/test/java/gov/va/med/cds/socket/server/rx_002.er7" ) );

            hl7er7Record = bufferedReader.readLine();

            while ( null != hl7er7Record )
            {
                record.append( hl7er7Record );

                hl7er7Record = bufferedReader.readLine();

            }

            bufferedReader.close();
        }
        catch ( FileNotFoundException e )
        {
            e.printStackTrace();
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }

        return new String( encodeToMllp( record.toString() ).array() );
    }


    private void connectToServer( )
        throws InterruptedException,
            IOException
    {

        IoConnector connector = new NioSocketConnector();

        //connector.getSessionConfig().setReadBufferSize( 2048 );

        connector.getFilterChain().addLast( "logger", new LoggingFilter() );

        //MinaMllpProtocolDecoder minaMllpProtocolDecoder = new MinaMllpProtocolDecoder();

        //MinaMllpProtocolEncoder minaMllpProtocolEncoder = new MinaMllpProtocolEncoder();

        //TextLineCodecFactory textLineCodecFactory = new TextLineCodecFactory( Charset.forName( "ISO-8859-1" ) );

        //textLineCodecFactory.setDecoderMaxLineLength( 2147483647 );

        //connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( textLineCodecFactory ) );

 //       connector.setHandler( new MinaClientHandlerDataTest(getMessage()));
        MinaClientHandlerDataTest minaClientHandlerDataTest = new MinaClientHandlerDataTest();
        minaClientHandlerDataTest.setValues(getMessage());
        connector.setHandler( minaClientHandlerDataTest);
        connector.connect( new InetSocketAddress( Integer.parseInt( "5001" ) ) );

        // connector.connect( new InetSocketAddress( "server.DNS           ", Integer.parseInt( PORT ) ) );

        //connector.connect( new InetSocketAddress( "server.aac.DNS   ", Integer.parseInt( PORT ) ) );

        //connector.connect( new InetSocketAddress( "server.URL       ", Integer.parseInt( LBPORT ) ) );

        //SQA2 HDR Only managed Node
        //connector.connect( new InetSocketAddress( "server.URL       ", Integer.parseInt( "5001" ) ) );

        connector.setConnectTimeoutMillis( 1000 );

    }


    public static void main( String args[] )
    {

        MultiThreadedClientConnector multiThreadedClientConnector = new MultiThreadedClientConnector();

        multiThreadedClientConnector.start();

    }

}
