package org.apache.maven.surefire.api.stream;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import javax.annotation.Nonnull;

import java.io.EOFException;
import java.io.File;
import java.math.BigInteger;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.CharsetDecoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.api.booter.Constants;
import org.apache.maven.surefire.api.booter.ForkedProcessEventType;
import org.apache.maven.surefire.api.event.Event;
import org.apache.maven.surefire.api.fork.ForkNodeArguments;
import org.apache.maven.surefire.api.stream.AbstractStreamDecoder.MalformedFrameException;
import org.apache.maven.surefire.api.stream.AbstractStreamDecoder.Memento;
import org.apache.maven.surefire.api.stream.AbstractStreamDecoder.Segment;
import org.junit.BeforeClass;
import org.junit.Test;

import static java.lang.Math.min;
import static java.lang.System.arraycopy;
import static java.nio.charset.CodingErrorAction.REPLACE;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.singletonMap;
import static org.apache.maven.surefire.api.booter.Constants.DEFAULT_STREAM_ENCODING;
import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDOUT;
import static org.apache.maven.surefire.api.stream.SegmentType.END_OF_FRAME;
import static org.assertj.core.api.Assertions.assertThat;
import static org.powermock.reflect.Whitebox.invokeMethod;

/**
 * The performance of "get( Integer )" is 13.5 nano seconds on i5/2.6GHz:
 * <pre>
 *     {@code
 *     TreeMap<Integer, ForkedProcessEventType> map = new TreeMap<>();
 *     map.get( hash );
 *     }
 * </pre>
 *
 * <br> The performance of getting event type by Segment is 33.7 nano seconds:
 * <pre>
 *     {@code
 *     Map<Segment, ForkedProcessEventType> map = new HashMap<>();
 *     byte[] array = ForkedProcessEventType.BOOTERCODE_STDOUT.getOpcode().getBytes( UTF_8 );
 *     map.get( new Segment( array, 0, array.length ) );
 *     }
 * </pre>
 *
 * <br> The performance of decoder:
 * <pre>
 *     {@code
 *     CharsetDecoder decoder = STREAM_ENCODING.newDecoder()
 *             .onMalformedInput( REPLACE )
 *             .onUnmappableCharacter( REPLACE );
 *     ByteBuffer buffer = ByteBuffer.wrap( ForkedProcessEventType.BOOTERCODE_STDOUT.getOpcode().getBytes( UTF_8 ) );
 *     CharBuffer chars = CharBuffer.allocate( 100 );
 *     decoder.reset().decode( buffer, chars, true );
 *
 *     String s = chars.flip().toString(); // 37 nanos = CharsetDecoder + toString
 *
 *     buffer.clear();
 *     chars.clear();
 *
 *     ForkedProcessEventType.byOpcode( s ); // 65 nanos = CharsetDecoder + toString + byOpcode
 *     }
 * </pre>
 *
 * <br> The performance of decoding 100 bytes via CharacterDecoder - 71 nano seconds:
 * <pre>
 *     {@code
 *     decoder.reset()
 *         .decode( buffer, chars, true ); // CharsetDecoder 71 nanos
 *     chars.flip().toString(); // CharsetDecoder + toString = 91 nanos
 *     }
 * </pre>
 *
 * <br> The performance of a pure string creation (instead of decoder) - 31.5 nano seconds:
 * <pre>
 *     {@code
 *     byte[] b = {};
 *     new String( b, UTF_8 );
 *     }
 * </pre>
 *
 * <br> The performance of CharsetDecoder with empty ByteBuffer:
 * <pre>
 *     {@code
 *     CharsetDecoder + ByteBuffer.allocate( 0 ) makes 11.5 nanos
 *     CharsetDecoder + ByteBuffer.allocate( 0 ) + toString() makes 16.1 nanos
 *     }
 * </pre>
 */
@SuppressWarnings( "checkstyle:magicnumber" )
public class AbstractStreamDecoderTest
{
    private static final Map<Segment, ForkedProcessEventType> EVENTS = new HashMap<>();

    private static final String PATTERN1 =
        "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";

    private static final String PATTERN2 = "€ab©c";

    private static final byte[] PATTERN2_BYTES =
        new byte[] {(byte) -30, (byte) -126, (byte) -84, 'a', 'b', (byte) 0xc2, (byte) 0xa9, 'c'};

    @BeforeClass
    public static void setup()
    {
        for ( ForkedProcessEventType event : ForkedProcessEventType.values() )
        {
            byte[] array = event.getOpcodeBinary();
            EVENTS.put( new Segment( array, 0, array.length ), event );
        }
    }

    @Test
    public void shouldDecodeHappyCase() throws Exception
    {
        CharsetDecoder decoder = UTF_8.newDecoder().onMalformedInput( REPLACE ).onUnmappableCharacter( REPLACE );
        ByteBuffer input = ByteBuffer.allocate( 1024 );
        ( (Buffer) input.put( PATTERN2_BYTES ) ).flip();
        int bytesToDecode = PATTERN2_BYTES.length;
        Buffer output = CharBuffer.allocate( 1024 );
        int readBytes = invokeMethod( AbstractStreamDecoder.class, "decodeString", decoder, input, output,
            bytesToDecode, true, 0 );

        assertThat( readBytes )
            .isEqualTo( bytesToDecode );

        assertThat( output.flip().toString() )
            .isEqualTo( PATTERN2 );
    }

    @Test
    public void shouldDecodeShifted() throws Exception
    {
        CharsetDecoder decoder = UTF_8.newDecoder().onMalformedInput( REPLACE ).onUnmappableCharacter( REPLACE );
        ByteBuffer input = ByteBuffer.allocate( 1024 );
        ( (Buffer) input.put( PATTERN1.getBytes( UTF_8 ) )
            .put( 90, (byte) 'A' )
            .put( 91, (byte) 'B' )
            .put( 92, (byte) 'C' ) )
            .position( 90 );
        Buffer output = CharBuffer.allocate( 1024 );
        int readBytes =
            invokeMethod( AbstractStreamDecoder.class, "decodeString", decoder, input, output, 2, true, 0 );

        assertThat( readBytes ).isEqualTo( 2 );

        assertThat( output.flip().toString() )
            .isEqualTo( "AB" );
    }

    @Test( expected = IllegalArgumentException.class )
    public void shouldNotDecode() throws Exception
    {
        CharsetDecoder decoder = UTF_8.newDecoder();
        ByteBuffer input = ByteBuffer.allocate( 100 );
        int bytesToDecode = 101;
        CharBuffer output = CharBuffer.allocate( 1000 );
        invokeMethod( AbstractStreamDecoder.class, "decodeString", decoder, input, output, bytesToDecode, true, 0 );
    }

    @Test
    public void shouldReadInt() throws Exception
    {
        Channel channel = new Channel( new byte[] {0x01, 0x02, 0x03, 0x04, ':'}, 1 );

        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();

        assertThat( thread.readInt( memento ) )
            .isEqualTo( new BigInteger( new byte[] {0x01, 0x02, 0x03, 0x04} ).intValue() );
    }

    @Test
    public void shouldReadInteger() throws Exception
    {
        Channel channel = new Channel( new byte[] {(byte) 0xff, 0x01, 0x02, 0x03, 0x04, ':'}, 1 );

        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        assertThat( thread.readInteger( memento ) )
            .isEqualTo( new BigInteger( new byte[] {0x01, 0x02, 0x03, 0x04} ).intValue() );
    }

    @Test
    public void shouldReadNullInteger() throws Exception
    {
        Channel channel = new Channel( new byte[] {(byte) 0x00, ':'}, 1 );

        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        assertThat( thread.readInteger( memento ) )
            .isNull();
    }

    @Test( expected = EOFException.class )
    public void shouldNotReadString() throws Exception
    {
        Channel channel = new Channel( PATTERN1.getBytes(), PATTERN1.length() );
        channel.read( ByteBuffer.allocate( 100 ) );

        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        invokeMethod( thread, "readString", memento, 10 );
    }

    @Test
    public void shouldReadString() throws Exception
    {
        Channel channel = new Channel( PATTERN1.getBytes(), PATTERN1.length() );

        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        String s = invokeMethod( thread, "readString", memento, 10 );
        assertThat( s )
            .isEqualTo( "0123456789" );
    }

    @Test
    public void shouldReadStringShiftedBuffer() throws Exception
    {
        StringBuilder s = new StringBuilder( 1100 );
        for ( int i = 0; i < 11; i++ )
        {
            s.append( PATTERN1 );
        }

        Channel channel = new Channel( s.toString().getBytes( UTF_8 ), s.length() );

        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        // whatever position will be compacted to 0
        ( (Buffer) ( (Buffer) memento.getByteBuffer() ).limit( 974 ) ).position( 974 );
        assertThat( (String) invokeMethod( thread, "readString", memento, PATTERN1.length() + 3 ) )
            .isEqualTo( PATTERN1 + "012" );
    }

    @Test
    public void shouldReadStringShiftedInput() throws Exception
    {
        StringBuilder s = new StringBuilder( 1100 );
        for ( int i = 0; i < 11; i++ )
        {
            s.append( PATTERN1 );
        }

        Channel channel = new Channel( s.toString().getBytes( UTF_8 ), s.length() );
        channel.read( ByteBuffer.allocate( 997 ) );

        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        assertThat( (String) invokeMethod( thread, "readString", memento, PATTERN1.length() ) )
            .isEqualTo( "789" + PATTERN1.substring( 0, 97 ) );
    }

    @Test
    public void shouldReadMultipleStringsAndShiftedInput() throws Exception
    {
        StringBuilder s = new StringBuilder( 5000 );

        for ( int i = 0; i < 50; i++ )
        {
            s.append( PATTERN1 );
        }

        Channel channel = new Channel( s.toString().getBytes( UTF_8 ), s.length() );
        channel.read( ByteBuffer.allocate( 1997 ) );

        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        // whatever position will be compacted to 0
        ( (Buffer) memento.getByteBuffer() ).limit( 974 ).position( 974 );

        StringBuilder expected = new StringBuilder( "789" );
        for ( int i = 0; i < 11; i++ )
        {
            expected.append( PATTERN1 );
        }
        expected.setLength( 1100 );
        assertThat( (String) invokeMethod( thread, "readString", memento, 1100 ) )
            .isEqualTo( expected.toString() );
    }

    @Test
    public void shouldDecode3BytesEncodedSymbol() throws Exception
    {
        byte[] encodedSymbol = new byte[] {(byte) -30, (byte) -126, (byte) -84};
        int countSymbols = 1024;
        byte[] input = new byte[encodedSymbol.length * countSymbols];
        for ( int i = 0; i < countSymbols; i++ )
        {
            arraycopy( encodedSymbol, 0, input, encodedSymbol.length * i, encodedSymbol.length );
        }

        Channel channel = new Channel( input, 64 * 1024 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );
        Memento memento = thread.new Memento();
        String decodedOutput = invokeMethod( thread, "readString", memento, input.length );

        assertThat( decodedOutput )
            .isEqualTo( new String( input, 0, input.length, UTF_8 ) );
    }

    @Test
    public void shouldDecode100Bytes() throws Exception
    {
        CharsetDecoder decoder = DEFAULT_STREAM_ENCODING.newDecoder()
            .onMalformedInput( REPLACE )
            .onUnmappableCharacter( REPLACE );
        // empty stream: CharsetDecoder + ByteBuffer.allocate( 0 ) makes 11.5 nanos
        // empty stream: CharsetDecoder + ByteBuffer.allocate( 0 ) + toString() makes 16.1 nanos
        ByteBuffer buffer = ByteBuffer.wrap( PATTERN1.getBytes( UTF_8 ) );
        CharBuffer chars = CharBuffer.allocate( 100 );
        // uncomment this section for a proper measurement of the exec time
        TimeUnit.SECONDS.sleep( 2 );
        System.gc();
        TimeUnit.SECONDS.sleep( 5 );
        String s = null;
        long l1 = System.currentTimeMillis();
        for ( int i = 0; i < 10_000_000; i++ )
        {
            decoder.reset()
                .decode( buffer, chars, true ); // CharsetDecoder 71 nanos
            s = ( (Buffer) chars ).flip().toString(); // CharsetDecoder + toString = 91 nanos
            ( (Buffer) buffer ).clear();
            ( (Buffer) chars ).clear();
        }
        long l2 = System.currentTimeMillis();
        System.out.println( "decoded 100 bytes within " + ( l2 - l1 ) + " millis (10 million cycles)" );
        assertThat( s )
            .isEqualTo( PATTERN1 );
    }

    @Test
    public void shouldReadEventType() throws Exception
    {
        byte[] array = BOOTERCODE_STDOUT.getOpcodeBinary();
        Map<Segment, ForkedProcessEventType> messageType =
            singletonMap( new Segment( array, 0, array.length ), BOOTERCODE_STDOUT );

        byte[] stream = ":maven-surefire-event:\u000E:std-out-stream:".getBytes( UTF_8 );
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(), messageType );

        Memento memento = thread.new Memento();
        memento.setCharset( UTF_8 );

        ForkedProcessEventType eventType = thread.readMessageType( memento );
        assertThat( eventType )
            .isEqualTo( BOOTERCODE_STDOUT );
    }

    @Test( expected = EOFException.class )
    public void shouldEventTypeReachedEndOfStream() throws Exception
    {
        byte[] stream = ":maven-surefire-event:\u000E:xxx".getBytes( UTF_8 );
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(), EVENTS );

        Memento memento = thread.new Memento();
        memento.setCharset( UTF_8 );
        thread.readMessageType( memento );
    }

    @Test( expected = MalformedFrameException.class )
    public void shouldEventTypeReachedMalformedHeader() throws Exception
    {
        byte[] stream = ":xxxxx-xxxxxxxx-xxxxx:\u000E:xxx".getBytes( UTF_8 );
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        memento.setCharset( UTF_8 );
        thread.readMessageType( memento );
    }

    @Test
    public void shouldReadEmptyString() throws Exception
    {
        byte[] stream = "\u0000\u0000\u0000\u0000::".getBytes( UTF_8 );
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        memento.setCharset( UTF_8 );

        assertThat( thread.readString( memento ) )
            .isEmpty();
    }

    @Test
    public void shouldReadNullString() throws Exception
    {
        byte[] stream = "\u0000\u0000\u0000\u0001:\u0000:".getBytes( UTF_8 );
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        memento.setCharset( UTF_8 );

        assertThat( thread.readString( memento ) )
            .isNull();
    }

    @Test
    public void shouldReadSingleCharString() throws Exception
    {
        byte[] stream = "\u0000\u0000\u0000\u0001:A:".getBytes( UTF_8 );
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        memento.setCharset( UTF_8 );

        assertThat( thread.readString( memento ) )
            .isEqualTo( "A" );
    }

    @Test
    public void shouldReadThreeCharactersString() throws Exception
    {
        byte[] stream = "\u0000\u0000\u0000\u0003:ABC:".getBytes( UTF_8 );
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        memento.setCharset( UTF_8 );

        assertThat( thread.readString( memento ) )
            .isEqualTo( "ABC" );
    }

    @Test
    public void shouldReadDefaultCharset() throws Exception
    {
        byte[] stream = "\u0005:UTF-8:".getBytes( US_ASCII );
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        memento.setCharset( UTF_8 );

        assertThat( thread.readCharset( memento ) )
            .isNotNull()
            .isEqualTo( UTF_8 );
    }

    @Test
    public void shouldReadNonDefaultCharset() throws Exception
    {
        byte[] stream = ( (char) 10 + ":ISO_8859_1:" ).getBytes( US_ASCII );
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        memento.setCharset( UTF_8 );

        assertThat( thread.readCharset( memento ) )
            .isNotNull()
            .isEqualTo( ISO_8859_1 );
    }

    @Test
    public void shouldSetNonDefaultCharset()
    {
        byte[] stream = {};
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );
        Memento memento = thread.new Memento();

        memento.setCharset( ISO_8859_1 );
        assertThat( memento.getDecoder().charset() ).isEqualTo( ISO_8859_1 );

        memento.setCharset( UTF_8 );
        assertThat( memento.getDecoder().charset() ).isEqualTo( UTF_8 );

        memento.reset();
        assertThat( memento.getDecoder() ).isNotNull();
        assertThat( memento.getDecoder().charset() ).isEqualTo( UTF_8 );
    }

    @Test( expected = MalformedFrameException.class )
    public void malformedCharset() throws Exception
    {
        byte[] stream = ( (char) 8 + ":ISO_8859:" ).getBytes( US_ASCII );
        Channel channel = new Channel( stream, 1 );
        Mock thread = new Mock( channel, new MockForkNodeArguments(),
            Collections.<Segment, ForkedProcessEventType>emptyMap() );

        Memento memento = thread.new Memento();
        memento.setCharset( UTF_8 );

        thread.readCharset( memento );
    }

    private static class Channel implements ReadableByteChannel
    {
        private final byte[] bytes;
        private final int chunkSize;
        protected int i;

        Channel( byte[] bytes, int chunkSize )
        {
            this.bytes = bytes;
            this.chunkSize = chunkSize;
        }

        @Override
        public int read( ByteBuffer dst )
        {
            if ( i == bytes.length )
            {
                return -1;
            }
            else if ( dst.hasRemaining() )
            {
                int length = min( min( chunkSize, bytes.length - i ), dst.remaining() ) ;
                dst.put( bytes, i, length );
                i += length;
                return length;
            }
            else
            {
                return 0;
            }
        }

        @Override
        public boolean isOpen()
        {
            return false;
        }

        @Override
        public void close()
        {
        }
    }

    private static class MockForkNodeArguments implements ForkNodeArguments
    {
        @Nonnull
        @Override
        public String getSessionId()
        {
            return null;
        }

        @Override
        public int getForkChannelId()
        {
            return 0;
        }

        @Nonnull
        @Override
        public File dumpStreamText( @Nonnull String text )
        {
            return null;
        }

        @Nonnull
        @Override
        public File dumpStreamException( @Nonnull Throwable t )
        {
            return null;
        }

        @Override
        public void logWarningAtEnd( @Nonnull String text )
        {
        }

        @Nonnull
        @Override
        public ConsoleLogger getConsoleLogger()
        {
            return null;
        }

        @Nonnull
        @Override
        public Object getConsoleLock()
        {
            return new Object();
        }

        @Override
        public File getEventStreamBinaryFile()
        {
            return null;
        }

        @Override
        public File getCommandStreamBinaryFile()
        {
            return null;
        }
    }

    private static class Mock extends AbstractStreamDecoder<Event, ForkedProcessEventType, SegmentType>
    {
        protected Mock( @Nonnull ReadableByteChannel channel, @Nonnull ForkNodeArguments arguments,
                        @Nonnull Map<Segment, ForkedProcessEventType> messageTypes )
        {
            super( channel, arguments, messageTypes );
        }

        @Override
        public Event decode() throws MalformedChannelException
        {
            throw new MalformedChannelException();
        }

        @Nonnull
        @Override
        protected byte[] getEncodedMagicNumber()
        {
            return Constants.MAGIC_NUMBER_FOR_EVENTS_BYTES;
        }

        @Nonnull
        @Override
        protected SegmentType[] nextSegmentType( @Nonnull ForkedProcessEventType messageType )
        {
            return new SegmentType[] {END_OF_FRAME};
        }

        @Nonnull
        @Override
        protected Event toMessage( @Nonnull ForkedProcessEventType messageType, @Nonnull Memento memento )
        {
            return null;
        }

        @Override
        public void close() throws Exception
        {
        }
    }
}
