

package gov.va.med.cds.util;


import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import gov.va.med.cds.exception.MllpIllegalEncodingException;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareRunner;

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

import org.junit.Test;
import org.junit.runner.RunWith;


@RunWith( SuiteAwareRunner.class )
public class MllpUtilTest
{
    
    @Test
    @Suite( groups = "checkintest" )
    public void testDecodeWithExtendedAscii( )
        throws Exception
    {
        String message = "TAKE TWO CAPSULES BY MOUTH TWICE A DAY ASCII CHARACTERS (E.G. Ã¦Â£Ã†Ã§ AND ASÃ‡Ã®Ã¯ CHÃ„Ã†ACTÃ‰R)NTE^1^^TESTING THE TRUNCATION OF DATA DUE TO EXTENDED ASCII IN PI^RE~REMARKS~613_52_12";
        
        Charset iso8859Charset = Charset.forName( "ISO-8859-1" );
        Charset defaultCharset = Charset.defaultCharset();
        
        // replace unencodable characters
        CharsetEncoder defaultCharsetEncoder = defaultCharset.newEncoder();
        CharsetEncoder iso8859CharsetEncoder = iso8859Charset.newEncoder();
        
        char[] messageChars = new char[message.length()];
        message.getChars(0, message.length(), messageChars, 0);
        for(char c : messageChars)
        {
            if(!iso8859CharsetEncoder.canEncode(c) || !defaultCharsetEncoder.canEncode(c))
            {
                message = message.replace(c, '?');
            }
        }
        
        ByteBuffer buffer = iso8859Charset.encode( ( ( char )MllpUtil.SOB ) + message + ( ( char )MllpUtil.EOB ) + "\r\r");
        ByteBuffer decodedBuffer = MllpUtil.decode( new ByteBuffer[] { buffer }, iso8859Charset, defaultCharset );
        String decodedMessage = new String(decodedBuffer.array(), defaultCharset);
        assertTrue( decodedMessage.equals( message ) );
    }



    @Test
    @Suite( groups = "checkintest" )
    public void testDecode( )
        throws Exception
    {
        String message = ( ( char )MllpUtil.SOB ) + "Hello this is a new message" + ( ( char )MllpUtil.EOB ) + "\r\r";
        ByteBuffer buffer = ByteBuffer.wrap( message.getBytes() );
        buffer = MllpUtil.decode( new ByteBuffer[] { buffer }, Charset.defaultCharset(), Charset.defaultCharset() );
        String decodedMessage = new String( buffer.array() );
        assertTrue( decodedMessage.equals( "Hello this is a new message" ) );
    }


    @Test
    @Suite( groups = "checkintest" )
    public void testDecodeExtendedAsciiString( )
        throws Exception
    {
        // æ£Æç te$nÃ‘
        byte[] b1 = { ( byte )230, ( byte )163, ( byte )198, ( byte )231, 32, 116, 101, 36, 110, ( byte )195, 96};
        byte[] b = { MllpUtil.SOB, ( byte )230, ( byte )163, ( byte )198, ( byte )231, 32, 116, 101, 36, 110, ( byte )195, 96, MllpUtil.EOB, 13, 13 };
        ByteBuffer buffer = ByteBuffer.wrap( b );
        buffer = MllpUtil.decode( new ByteBuffer[] { buffer }, Charset.forName( "ISO-8859-1" ), Charset.forName("ISO-8859-1") );
        String decodedMessage = new String( buffer.array(), "ISO-8859-1" );
        String originalMsg = new String( b1, "ISO-8859-1" );
        assertTrue( decodedMessage.equals( originalMsg ) );
    }


    @Test( expected = MllpIllegalEncodingException.class )
    @Suite( groups = "checkintest" )
    public void testDecodeWithNonWhiteSpaceAfterEob( )
        throws Exception
    {
        String message = ( ( char )MllpUtil.SOB ) + "Hello this is a new message" + ( ( char )MllpUtil.EOB ) + "NonWhitespace\r\r";
        ByteBuffer buffer = ByteBuffer.wrap( message.getBytes() );
        buffer = MllpUtil.decode( new ByteBuffer[] { buffer }, Charset.defaultCharset(), Charset.defaultCharset() );
        fail( "Expected MllpIllegalEncodingException" );
    }


    @Test
    @Suite( groups = "checkintest" )
    public void testEncode( )
        throws Exception
    {
        String message = "Hello this is a new message";
        ByteBuffer buffer = ByteBuffer.wrap( message.getBytes() );
        buffer = MllpUtil.encode( buffer, Charset.defaultCharset(), Charset.defaultCharset() );
        String encodedMessage = new String( buffer.array() );
        assertTrue( encodedMessage.equals( ( ( char )MllpUtil.SOB ) + message + ( ( char )MllpUtil.CR ) + ( ( char )MllpUtil.EOB )
                        + ( ( char )MllpUtil.CR ) ) );
    }


    @Test
    @Suite( groups = "checkintest" )
    public void testEncodedPartial( )
        throws Exception
    {
        String message = "Hello this is a new message";
        String messagePlus = ( ( char )MllpUtil.SOB ) + message;
        ByteBuffer buffer = ByteBuffer.wrap( messagePlus.getBytes() );
        buffer = MllpUtil.encode( buffer, Charset.defaultCharset(), Charset.defaultCharset() );
        String encodedMessage = new String( buffer.array() );
        assertTrue( encodedMessage.equals( ( ( char )MllpUtil.SOB ) + message + ( ( char )MllpUtil.CR ) + ( ( char )MllpUtil.EOB )
                        + ( ( char )MllpUtil.CR ) ) );
    }


    @Test
    @Suite( groups = "checkintest" )
    public void testEncodedFull( )
        throws Exception
    {
        String message = "Hello this is a new message";
        String messagePlus = ( ( char )MllpUtil.SOB ) + message + ( ( char )MllpUtil.EOB ) + ( ( char )MllpUtil.CR );
        ByteBuffer buffer = ByteBuffer.wrap( messagePlus.getBytes() );
        buffer = MllpUtil.encode( buffer, Charset.defaultCharset(), Charset.defaultCharset() );
        String encodedMessage = new String( buffer.array() );
        assertTrue( encodedMessage.equals( ( ( char )MllpUtil.SOB ) + message + ( ( char )MllpUtil.CR ) + ( ( char )MllpUtil.EOB )
                        + ( ( char )MllpUtil.CR ) ) );
    }

}
