package org.apache.maven.plugin.surefire.extensions;

/*
 * 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 org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.api.booter.Command;
import org.apache.maven.surefire.extensions.CommandReader;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.WritableByteChannel;
import java.util.Iterator;

import static java.util.Arrays.asList;
import static org.apache.maven.surefire.api.booter.Command.TEST_SET_FINISHED;
import static org.apache.maven.surefire.api.booter.MasterProcessCommand.NOOP;
import static org.apache.maven.surefire.api.booter.MasterProcessCommand.RUN_CLASS;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

/**
 * Tests for {@link StreamFeeder}.
 */
public class StreamFeederTest
{
    private final ByteArrayOutputStream out = new ByteArrayOutputStream();
    private final WritableByteChannel channel = mock( WritableByteChannel.class );
    private final CommandReader commandReader = mock( CommandReader.class );
    private StreamFeeder streamFeeder;

    @Before
    public void setup() throws IOException
    {
        final Iterator<Command> it = asList( new Command( RUN_CLASS, "pkg.ATest" ), TEST_SET_FINISHED ).iterator();
        when( commandReader.readNextCommand() )
            .thenAnswer( new Answer<Command>()
            {
                @Override
                public Command answer( InvocationOnMock invocation )
                {
                    return it.hasNext() ? it.next() : null;
                }
            } );
    }

    @After
    public void close() throws IOException
    {
        if ( streamFeeder != null )
        {
            streamFeeder.disable();
            streamFeeder.close();
        }
    }

    @Test
    public void shouldEncodeCommandToStream() throws Exception
    {
        when( channel.write( any( ByteBuffer.class ) ) )
            .thenAnswer( new Answer<Object>()
            {
                @Override
                public Object answer( InvocationOnMock invocation ) throws IOException
                {
                    ByteBuffer bb = invocation.getArgument( 0 );
                    bb.flip();
                    out.write( bb.array() );
                    return 0;
                }
            } );

        ConsoleLogger logger = mock( ConsoleLogger.class );
        streamFeeder = new StreamFeeder( "t", channel, commandReader, logger );
        streamFeeder.start();

        streamFeeder.join();
        String commands = out.toString();

        assertThat( commands )
            .isEqualTo( ":maven-surefire-command:run-testclass:pkg.ATest::maven-surefire-command:testset-finished:" );

        verify( channel, times( 1 ) )
            .close();

        assertThat( streamFeeder.getException() )
            .isNull();

        verifyZeroInteractions( logger );
    }

    @Test
    public void shouldFailThread() throws Exception
    {
        when( channel.write( any( ByteBuffer.class ) ) )
            .thenAnswer( new Answer<Object>()
            {
                @Override
                public Object answer( InvocationOnMock invocation ) throws IOException
                {
                    throw new IOException();
                }
            } );

        ConsoleLogger logger = mock( ConsoleLogger.class );
        streamFeeder = new StreamFeeder( "t", channel, commandReader, logger );
        streamFeeder.start();

        streamFeeder.join();

        assertThat( out.size() )
            .isZero();

        verify( channel, times( 1 ) )
            .close();

        assertThat( streamFeeder.getException() )
            .isNotNull()
            .isInstanceOf( IOException.class );

        verifyZeroInteractions( logger );
    }

    @Test( expected = IllegalArgumentException.class )
    public void shouldFailWithoutData()
    {
        StreamFeeder.encode( RUN_CLASS );
    }

    @Test( expected = IllegalArgumentException.class )
    public void shouldFailWithData()
    {
        StreamFeeder.encode( NOOP, "" );
    }
}
