package org.apache.maven.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.booterclient.MockReporter;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream.TestLessInputStreamBuilder;
import org.apache.maven.plugin.surefire.extensions.SurefireForkNodeFactory;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.eventapi.ControlByeEvent;
import org.apache.maven.surefire.eventapi.Event;
import org.apache.maven.surefire.extensions.util.CountdownCloseable;
import org.junit.Test;

import javax.annotation.Nonnull;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
 *
 */
public class ForkChannelTest
{
    private static final long TESTCASE_TIMEOUT = 30_000L;

    private final AtomicBoolean hasError = new AtomicBoolean();

    @Test( timeout = TESTCASE_TIMEOUT )
    public void shouldRequestReplyMessagesViaTCP() throws Exception
    {
        ForkNodeArguments forkNodeArguments = new ForkNodeArguments()
        {
            @Override
            public int getForkChannelId()
            {
                return 1;
            }

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

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

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

        ForkNodeFactory factory = new SurefireForkNodeFactory();
        try ( ForkChannel channel = factory.createForkChannel( forkNodeArguments ) )
        {
            assertThat( channel.getArguments().getForkChannelId() )
                .isEqualTo( 1 );

            assertThat( channel.getCountdownCloseablePermits() )
                .isEqualTo( 3 );

            assertThat( channel.getForkNodeConnectionString() )
                .startsWith( "tcp://127.0.0.1:" )
                .isNotEqualTo( "tcp://127.0.0.1:" );

            URI uri = new URI( channel.getForkNodeConnectionString() );

            assertThat( uri.getPort() )
                .isPositive();

            final TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
            TestLessInputStream commandReader = builder.build();
            final CountDownLatch isCloseableCalled = new CountDownLatch( 1 );
            Closeable closeable = new Closeable()
            {
                @Override
                public void close()
                {
                    isCloseableCalled.countDown();
                }
            };
            CountdownCloseable cc = new CountdownCloseable( closeable, 2 );
            Consumer consumer = new Consumer();

            Client client = new Client( uri.getPort() );
            client.start();

            channel.connectToClient();
            channel.bindCommandReader( commandReader, null ).start();
            ReadableByteChannel stdOut = mock( ReadableByteChannel.class );
            when( stdOut.read( any( ByteBuffer.class ) ) ).thenReturn( -1 );
            channel.bindEventHandler( consumer, cc, stdOut ).start();

            commandReader.noop();

            client.join( TESTCASE_TIMEOUT );

            assertThat( hasError.get() )
                .isFalse();

            assertThat( isCloseableCalled.await( TESTCASE_TIMEOUT, MILLISECONDS ) )
                .isTrue();

            assertThat( consumer.lines )
                .hasSize( 1 );

            assertThat( consumer.lines.element() )
                .isInstanceOf( ControlByeEvent.class );
        }
    }

    private static class Consumer implements EventHandler<Event>
    {
        final Queue<Event> lines = new ConcurrentLinkedQueue<>();

        @Override
        public void handleEvent( @Nonnull Event s )
        {
            lines.add( s );
        }
    }

    private final class Client extends Thread
    {
        private final int port;

        private Client( int port )
        {
            this.port = port;
        }

        @Override
        public void run()
        {
            try ( Socket socket = new Socket( "127.0.0.1", port ) )
            {
                byte[] data = new byte[128];
                int readLength = socket.getInputStream().read( data );
                String token = new String( data, 0, readLength, US_ASCII );
                assertThat( token ).isEqualTo( ":maven-surefire-command:noop:" );
                socket.getOutputStream().write( ":maven-surefire-event:bye:".getBytes( US_ASCII ) );
            }
            catch ( IOException e )
            {
                hasError.set( true );
                e.printStackTrace();
                throw new IllegalStateException( e );
            }
            catch ( RuntimeException e )
            {
                hasError.set( true );
                e.printStackTrace();
                throw e;
            }
        }
    }
}
