package phex.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.nio.charset.Charset;
import java.util.Arrays;

import junit.framework.TestCase;

import phex.common.address.DestAddress;
import phex.common.bandwidth.BandwidthController;
import phex.io.buffer.ByteBuffer;
import phex.net.connection.Connection;
import phex.net.repres.SocketFacade;
import phex.utils.IOUtil;

public class TestConnection extends TestCase
{
    
    public void testWriteByteBuffer() throws IOException
    {
        ByteBuffer buffer = ByteBuffer.allocate( 20 );
        byte[] data = "Hello World".getBytes();
        buffer.put( data, 0, data.length );
        buffer.flip();
        DummySocketFacade socketFac = new DummySocketFacade( data );
        Connection con = new Connection( socketFac, 
            BandwidthController.acquireBandwidthController( "JUnitText", Long.MAX_VALUE ) );
        con.write( buffer );
        byte[] resultData = socketFac.outStream.toByteArray();
        assertTrue( Arrays.equals( data, resultData ) );
        assertEquals( buffer.position(), data.length );
        assertEquals( buffer.remaining(), 0 );
    }
    
    public void testReadByteBuffer() throws IOException
    {
        
        String testString = "Hello World";
        byte[] data = testString.getBytes();

        DummySocketFacade socketFac = new DummySocketFacade( data );
        Connection con = new Connection( socketFac, 
            BandwidthController.acquireBandwidthController( "JUnitText", Long.MAX_VALUE ) );
        ByteBuffer buffer = ByteBuffer.allocate( 20 );
        con.read( buffer );
        buffer.flip();
        int size = buffer.remaining();
        assertEquals( data.length, size );
        String resultString = buffer.getString( Charset.forName( "UTF-8" ).newDecoder() );
        assertEquals( testString, resultString );
        assertEquals( buffer.position(), data.length );
        assertEquals( buffer.remaining(), 0 );
    }
    
    private class DummySocketFacade implements SocketFacade
    {
        private ByteArrayInputStream inStream;
        private ByteArrayOutputStream outStream;
        
        public DummySocketFacade( byte[] inStreamContent )
        {
            inStream = new ByteArrayInputStream( inStreamContent );
            outStream = new ByteArrayOutputStream( );
        }

        public void close() throws IOException
        {
            IOUtil.closeQuietly( inStream );
            IOUtil.closeQuietly( outStream );
        }

        public InputStream getInputStream() throws IOException
        {
            return inStream;
        }

        public OutputStream getOutputStream() throws IOException
        {
            return outStream;
        }

        public DestAddress getRemoteAddress()
        {
            return null;
        }

        public void setSoTimeout(int socketRWTimeout) throws SocketException
        {
        }        
    }
}
