package org.apache.maven.surefire.booter;

/*
 * 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.surefire.api.booter.MasterProcessChannelDecoder;
import org.apache.maven.surefire.api.booter.MasterProcessChannelEncoder;
import org.apache.maven.surefire.api.report.StackTraceWriter;
import org.apache.maven.surefire.api.util.internal.WritableBufferedByteChannel;
import org.apache.maven.surefire.booter.spi.AbstractMasterProcessChannelProcessorFactory;
import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelDecoder;
import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder;
import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelProcessorFactory;
import org.apache.maven.surefire.booter.spi.SurefireMasterProcessChannelProcessorFactory;
import org.apache.maven.surefire.shared.utils.cli.ShutdownHookUtils;
import org.apache.maven.surefire.spi.MasterProcessChannelProcessorFactory;
import org.junit.Rule;
import org.junit.Test;
import org.junit.function.ThrowingRunnable;
import org.junit.rules.ErrorCollector;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.maven.surefire.api.util.internal.Channels.newBufferedChannel;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.same;
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.powermock.api.mockito.PowerMockito.doAnswer;
import static org.powermock.api.mockito.PowerMockito.doCallRealMethod;
import static org.powermock.api.mockito.PowerMockito.doNothing;
import static org.powermock.api.mockito.PowerMockito.doThrow;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.verifyNoMoreInteractions;
import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.reflect.Whitebox.invokeMethod;
import static org.powermock.reflect.Whitebox.setInternalState;

/**
 * PowerMock tests for {@link ForkedBooter}.
 */
@RunWith( PowerMockRunner.class )
@PrepareForTest( {
                     PpidChecker.class,
                     ForkedBooter.class,
                     LegacyMasterProcessChannelEncoder.class,
                     ShutdownHookUtils.class
} )
@PowerMockIgnore( { "org.jacoco.agent.rt.*", "com.vladium.emma.rt.*" } )
public class ForkedBooterMockTest
{
    @Rule
    public final ErrorCollector errorCollector = new ErrorCollector();

    @Mock
    private PpidChecker pluginProcessChecker;

    @Mock
    private ForkedBooter booter;

    @Mock
    private MasterProcessChannelProcessorFactory channelProcessorFactory;

    @Mock
    private LegacyMasterProcessChannelEncoder eventChannel;

    @Captor
    private ArgumentCaptor<StackTraceWriter> capturedStackTraceWriter;

    @Captor
    private ArgumentCaptor<Boolean> capturedBoolean;

    @Captor
    private ArgumentCaptor<String[]> capturedArgs;

    @Captor
    private ArgumentCaptor<ForkedBooter> capturedBooter;

    @Test
    public void shouldCheckNewPingMechanism() throws Exception
    {
        boolean canUse = invokeMethod( ForkedBooter.class, "canUseNewPingMechanism", (PpidChecker) null );
        assertThat( canUse ).isFalse();

        when( pluginProcessChecker.canUse() ).thenReturn( false );
        canUse = invokeMethod( ForkedBooter.class, "canUseNewPingMechanism", pluginProcessChecker );
        assertThat( canUse ).isFalse();

        when( pluginProcessChecker.canUse() ).thenReturn( true );
        canUse = invokeMethod( ForkedBooter.class, "canUseNewPingMechanism", pluginProcessChecker );
        assertThat( canUse ).isTrue();
    }

    @Test
    public void testMain() throws Exception
    {
        mockStatic( ForkedBooter.class );

        doCallRealMethod()
                .when( ForkedBooter.class, "run", capturedBooter.capture(), capturedArgs.capture() );

        String[] args = new String[]{ "/", "dump", "surefire.properties", "surefire-effective.properties" };
        invokeMethod( ForkedBooter.class, "run", booter, args );

        assertThat( capturedBooter.getAllValues() )
                .hasSize( 1 )
                .contains( booter );

        assertThat( capturedArgs.getAllValues() )
                .hasSize( 1 );
        assertThat( capturedArgs.getAllValues().get( 0 )[0] )
                .isEqualTo( "/" );
        assertThat( capturedArgs.getAllValues().get( 0 )[1] )
                .isEqualTo( "dump" );
        assertThat( capturedArgs.getAllValues().get( 0 )[2] )
                .isEqualTo( "surefire.properties" );
        assertThat( capturedArgs.getAllValues().get( 0 )[3] )
                .isEqualTo( "surefire-effective.properties" );

        verifyPrivate( booter, times( 1 ) )
                .invoke( "setupBooter", same( args[0] ), same( args[1] ), same( args[2] ), same( args[3] ) );

        verifyPrivate( booter, times( 1 ) )
                .invoke( "execute" );

        verifyNoMoreInteractions( booter );
    }

    @Test
    public void testMainWithError() throws Exception
    {
        mockStatic( ForkedBooter.class );

        doCallRealMethod()
                .when( ForkedBooter.class, "run", any( ForkedBooter.class ), any( String[].class ) );

        doThrow( new RuntimeException( "dummy exception" ) )
                .when( booter, "execute" );

        doNothing()
                .when( booter, "setupBooter",
                        any( String.class ), any( String.class ), any( String.class ), any( String.class ) );

        setInternalState( booter, "eventChannel", eventChannel );

        String[] args = new String[]{ "/", "dump", "surefire.properties", "surefire-effective.properties" };
        invokeMethod( ForkedBooter.class, "run", booter, args );

        verifyPrivate( booter, times( 1 ) )
                .invoke( "setupBooter", same( args[0] ), same( args[1] ), same( args[2] ), same( args[3] ) );

        verifyPrivate( booter, times( 1 ) )
                .invoke( "execute" );

        verify( eventChannel, times( 1 ) )
                .consoleErrorLog( capturedStackTraceWriter.capture(), capturedBoolean.capture() );
        assertThat( capturedStackTraceWriter.getValue() )
                .isNotNull();
        assertThat( capturedStackTraceWriter.getValue().smartTrimmedStackTrace() )
                .isEqualTo( "test subsystem#no method RuntimeException dummy exception" );
        assertThat( capturedStackTraceWriter.getValue().getThrowable().getTarget() )
                .isNotNull()
                .isInstanceOf( RuntimeException.class );
        assertThat( capturedStackTraceWriter.getValue().getThrowable().getTarget().getMessage() )
                .isEqualTo( "dummy exception" );

        verifyPrivate( booter, times( 1 ) )
                .invoke( "cancelPingScheduler" );

        verifyPrivate( booter, times( 1 ) )
                .invoke( "exit1" );

        verifyNoMoreInteractions( booter );
    }

    @Test
    public void shouldNotCloseChannelProcessorFactory() throws Exception
    {
        setInternalState( booter, "channelProcessorFactory", (MasterProcessChannelProcessorFactory) null );

        doCallRealMethod()
            .when( booter, "closeForkChannel" );

        invokeMethod( booter, "closeForkChannel" );

        verifyZeroInteractions( channelProcessorFactory );
    }

    @Test
    public void shouldCloseChannelProcessorFactory() throws Exception
    {
        setInternalState( booter, "channelProcessorFactory", channelProcessorFactory );

        doCallRealMethod()
            .when( booter, "closeForkChannel" );

        invokeMethod( booter, "closeForkChannel" );

        verify( channelProcessorFactory, times( 1 ) )
            .close();
        verifyNoMoreInteractions( channelProcessorFactory );
    }

    @Test
    public void shouldFailOnCloseChannelProcessorFactory() throws Exception
    {
        setInternalState( booter, "channelProcessorFactory", channelProcessorFactory );

        doThrow( new IOException() )
            .when( channelProcessorFactory )
            .close();

        doCallRealMethod()
            .when( booter, "closeForkChannel" );

        invokeMethod( booter, "closeForkChannel" );

        verify( channelProcessorFactory, times( 1 ) )
            .close();
        verifyNoMoreInteractions( channelProcessorFactory );
    }

    @Test
    public void shouldLookupLegacyDecoderFactory() throws Exception
    {
        mockStatic( ForkedBooter.class );

        doCallRealMethod()
            .when( ForkedBooter.class, "lookupDecoderFactory", anyString() );

        try ( final MasterProcessChannelProcessorFactory factory =
                  invokeMethod( ForkedBooter.class, "lookupDecoderFactory", "pipe://3" ) )
        {
            assertThat( factory ).isInstanceOf( LegacyMasterProcessChannelProcessorFactory.class );

            assertThat( factory.canUse( "pipe://3" ) ).isTrue();

            assertThat( factory.canUse( "-- whatever --" ) ).isFalse();

            errorCollector.checkThrows( MalformedURLException.class, new ThrowingRunnable()
            {
                @Override
                public void run() throws Throwable
                {
                    factory.connect( "tcp://localhost:123" );
                    fail();
                }
            } );

            factory.connect( "pipe://3" );

            MasterProcessChannelDecoder decoder = factory.createDecoder();
            assertThat( decoder ).isInstanceOf( LegacyMasterProcessChannelDecoder.class );
            MasterProcessChannelEncoder encoder = factory.createEncoder();
            assertThat( encoder ).isInstanceOf( LegacyMasterProcessChannelEncoder.class );
        }
    }

    @Test
    @SuppressWarnings( "checkstyle:magicnumber" )
    public void shouldScheduleFlushes() throws Exception
    {
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        class Factory extends AbstractMasterProcessChannelProcessorFactory
        {
            @Override
            public boolean canUse( String channelConfig )
            {
                return false;
            }

            @Override
            public void connect( String channelConfig )
            {
            }

            @Override
            public MasterProcessChannelDecoder createDecoder()
            {
                return null;
            }

            @Override
            public MasterProcessChannelEncoder createEncoder()
            {
                return null;
            }

            public void runScheduler() throws InterruptedException
            {
                final WritableBufferedByteChannel channel = newBufferedChannel( out );
                schedulePeriodicFlusher( 100, channel );
                Thread t = new Thread()
                {
                    @Override
                    public void run()
                    {
                        for ( int i = 0; i < 10; i++ )
                        {
                            try
                            {
                                channel.write( ByteBuffer.wrap( new byte[] {1} ) );
                                Thread.sleep( 75 );
                            }
                            catch ( Exception e )
                            {
                                //
                            }
                        }
                    }
                };
                t.setDaemon( true );
                t.start();
                t.join( 5000L );
            }
        }

        Factory factory = new Factory();
        factory.runScheduler();
        factory.close();
        assertThat( out.size() ).isPositive();
        assertThat( out.size() ).isLessThanOrEqualTo( 10 );
    }

    @Test
    public void shouldLookupSurefireDecoderFactory() throws Exception
    {
        mockStatic( ForkedBooter.class );

        doCallRealMethod()
            .when( ForkedBooter.class, "lookupDecoderFactory", anyString() );

        try ( ServerSocketChannel server = ServerSocketChannel.open() )
        {
            server.bind( new InetSocketAddress( 0 ) );
            int serverPort = ( (InetSocketAddress) server.getLocalAddress() ).getPort();

            try ( MasterProcessChannelProcessorFactory factory =
                     invokeMethod( ForkedBooter.class, "lookupDecoderFactory", "tcp://localhost:" + serverPort ) )
            {
                assertThat( factory )
                    .isInstanceOf( SurefireMasterProcessChannelProcessorFactory.class );

                assertThat( factory.canUse( "tcp://localhost:" + serverPort ) )
                    .isTrue();

                assertThat( factory.canUse( "-- whatever --" ) )
                    .isFalse();

                errorCollector.checkThrows( MalformedURLException.class, new ThrowingRunnable()
                {
                    @Override
                    public void run() throws Throwable
                    {
                        factory.connect( "pipe://1" );
                        fail();
                    }
                } );

                errorCollector.checkThrows( IOException.class, new ThrowingRunnable()
                {
                    @Override
                    public void run() throws Throwable
                    {
                        factory.connect( "tcp://localhost:123\u0000\u0000\u0000" );
                        fail();
                    }
                } );

                factory.connect( "tcp://localhost:" + serverPort );

                MasterProcessChannelDecoder decoder = factory.createDecoder();
                assertThat( decoder )
                    .isInstanceOf( LegacyMasterProcessChannelDecoder.class );
                MasterProcessChannelEncoder encoder = factory.createEncoder();
                assertThat( encoder )
                    .isInstanceOf( LegacyMasterProcessChannelEncoder.class );
            }
        }
    }

    @Test
    public void shouldAuthenticate() throws Exception
    {
        mockStatic( ForkedBooter.class );

        doCallRealMethod()
            .when( ForkedBooter.class, "lookupDecoderFactory", anyString() );

        try ( final ServerSocketChannel server = ServerSocketChannel.open() )
        {
            server.bind( new InetSocketAddress( 0 ) );
            int serverPort = ( (InetSocketAddress) server.getLocalAddress() ).getPort();
            final String uuid = UUID.randomUUID().toString();
            String url = "tcp://localhost:" + serverPort + "?sessionId=" + uuid;
            try ( final MasterProcessChannelProcessorFactory factory =
                      invokeMethod( ForkedBooter.class, "lookupDecoderFactory", url ) )
            {
                assertThat( factory )
                    .isInstanceOf( SurefireMasterProcessChannelProcessorFactory.class );

                FutureTask<Boolean> task = new FutureTask<>( new Callable<Boolean>()
                {
                    @Override
                    public Boolean call()
                    {
                        try
                        {
                            SocketChannel channel = server.accept();
                            ByteBuffer bb = ByteBuffer.allocate( uuid.length() );
                            int read = channel.read( bb );
                            assertThat( read )
                                .isEqualTo( uuid.length() );
                            bb.flip();
                            assertThat( new String( bb.array(), US_ASCII ) )
                                .isEqualTo( uuid );
                            return true;
                        }
                        catch ( IOException e )
                        {
                            return false;
                        }
                    }
                } );

                Thread t = new Thread( task );
                t.setDaemon( true );
                t.start();

                factory.connect( url );

                try
                {
                    task.get( 10, SECONDS );
                }
                finally
                {
                    factory.close();
                }
            }
        }
    }

    @Test
    public void testFlushEventChannelOnExit() throws Exception
    {
        mockStatic( ShutdownHookUtils.class );

        final MasterProcessChannelEncoder eventChannel = mock( MasterProcessChannelEncoder.class );
        ForkedBooter booter = new ForkedBooter();
        setInternalState( booter, "eventChannel", eventChannel );

        doAnswer( new Answer<Object>()
        {
            @Override
            public Object answer( InvocationOnMock invocation )
            {
                Thread t = invocation.getArgument( 0 );
                assertThat( t.isDaemon() ).isTrue();
                t.run();
                verify( eventChannel, times( 1 ) ).onJvmExit();
                return null;
            }
        } ).when( ShutdownHookUtils.class, "addShutDownHook", any( Thread.class ) );
        invokeMethod( booter, "flushEventChannelOnExit" );
    }

    @Test
    public void shouldParseUUID() throws Exception
    {
        UUID uuid = UUID.randomUUID();
        URI uri = new URI( "tcp://localhost:12345?sessionId=" + uuid );
        String parsed = invokeMethod( SurefireMasterProcessChannelProcessorFactory.class, "extractSessionId", uri );
        assertThat( parsed )
            .isEqualTo( uuid.toString() );
    }

    @Test
    public void shouldNotParseUUID() throws Exception
    {
        UUID uuid = UUID.randomUUID();
        URI uri = new URI( "tcp://localhost:12345?xxx=" + uuid );
        String parsed = invokeMethod( SurefireMasterProcessChannelProcessorFactory.class, "extractSessionId", uri );
        assertThat( parsed )
            .isNull();
    }
}
