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

/*
 * 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.StartupReportConfiguration;
import org.apache.maven.plugin.surefire.SurefireProperties;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.AbstractCommandReader;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
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.booterclient.lazytestprovider.TestProvidingInputStream;
import org.apache.maven.plugin.surefire.booterclient.output.ForkClient;
import org.apache.maven.plugin.surefire.extensions.LegacyForkNodeFactory;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
import org.apache.maven.surefire.booter.AbstractPathConfiguration;
import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.PropertiesWrapper;
import org.apache.maven.surefire.booter.ProviderConfiguration;
import org.apache.maven.surefire.api.booter.Shutdown;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.api.report.ReporterConfiguration;
import org.apache.maven.surefire.shared.compress.archivers.zip.Zip64Mode;
import org.apache.maven.surefire.shared.compress.archivers.zip.ZipArchiveEntry;
import org.apache.maven.surefire.shared.compress.archivers.zip.ZipArchiveOutputStream;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayDeque;
import java.util.Collections;
import java.util.jar.Manifest;
import java.util.zip.Deflater;

import static org.fest.util.Files.delete;
import static org.hamcrest.Matchers.containsString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.powermock.reflect.Whitebox.invokeMethod;

/**
 *
 */
public class ForkStarterTest
{
    private static String baseDir = System.getProperty( "user.dir" );
    private static File tmp;

    @Rule
    public final ExpectedException e = ExpectedException.none();

    @BeforeClass
    public static void prepareFiles() throws IOException
    {
        File target = new File( baseDir, "target" );
        tmp = new File( target, "tmp" );
        tmp.mkdirs();
        File booter = new File( tmp, "surefirebooter.jar" );
        booter.createNewFile();

        try ( ZipArchiveOutputStream zos = new ZipArchiveOutputStream( new FileOutputStream( booter ) ) )
        {
            zos.setUseZip64( Zip64Mode.Never );
            zos.setLevel( Deflater.NO_COMPRESSION );

            ZipArchiveEntry ze = new ZipArchiveEntry( "META-INF/MANIFEST.MF" );
            zos.putArchiveEntry( ze );

            Manifest man = new Manifest();

            man.getMainAttributes().putValue( "Manifest-Version", "1.0" );
            man.getMainAttributes().putValue( "Main-Class", MainClass.class.getName() );

            man.write( zos );

            zos.closeArchiveEntry();

            ze = new ZipArchiveEntry( "org/apache/maven/plugin/surefire/booterclient/MainClass.class" );
            zos.putArchiveEntry( ze );
            String classesDir = Paths.get( target.getPath(), "test-classes" ).toString();
            Path cls = Paths.get( classesDir, "org", "apache", "maven", "plugin", "surefire", "booterclient",
                "MainClass.class" );
            zos.write( Files.readAllBytes( cls ) );
            zos.closeArchiveEntry();
        }
    }

    @AfterClass
    public static void deleteTmp()
    {
        delete( tmp );
    }

    @Test
    public void processShouldExitWithoutSayingGoodBye() throws Exception
    {
        ReporterConfiguration reporterConfiguration = new ReporterConfiguration( tmp, true );

        ProviderConfiguration providerConfiguration = mock( ProviderConfiguration.class );
        when( providerConfiguration.getReporterConfiguration() )
            .thenReturn( reporterConfiguration );
        when( providerConfiguration.getShutdown() )
            .thenReturn( Shutdown.EXIT );

        StartupConfiguration startupConfiguration = mock( StartupConfiguration.class );
        when( startupConfiguration.getClasspathConfiguration() )
            .thenReturn( new ClasspathConfig() );
        when( startupConfiguration.getClassLoaderConfiguration() )
            .thenReturn( new ClassLoaderConfiguration( false, false ) );
        when( startupConfiguration.getProviderClassName() )
            .thenReturn( MainClass.class.getName() );

        ForkConfiguration forkConfiguration = mock( ForkConfiguration.class );
        when( forkConfiguration.getWorkingDirectory() )
            .thenReturn( tmp );
        when( forkConfiguration.getTempDirectory() )
            .thenReturn( tmp );
        when( forkConfiguration.getPluginPlatform() )
            .thenReturn( new Platform() );
        OutputStreamFlushableCommandline cli = new OutputStreamFlushableCommandline();
        cli.setWorkingDirectory( tmp );
        cli.setExecutable( System.getProperty( "java.home" ) + "/bin/java" );
        cli.createArg().setLine( "-jar" );
        cli.createArg().setLine( "surefirebooter.jar" );
        cli.createArg().setLine( "fail" );
        when( forkConfiguration.createCommandLine( eq( startupConfiguration ), eq( 1 ), eq( tmp ) ) )
            .thenReturn( cli );

        StartupReportConfiguration startupReportConfiguration = new StartupReportConfiguration( true, true, null,
            false, tmp, true, "", null, false, 0, null, null, true, null, null, null );

        ConsoleLogger logger = mock( ConsoleLogger.class );

        ForkStarter forkStarter = new ForkStarter( providerConfiguration, startupConfiguration, forkConfiguration,
            0, startupReportConfiguration, logger );

        DefaultReporterFactory reporterFactory = new DefaultReporterFactory( startupReportConfiguration, logger, 1 );

        e.expect( SurefireBooterForkException.class );
        e.expectMessage( containsString( "Process Exit Code: 1" ) );
        e.expectMessage( containsString( "The forked VM terminated without properly saying goodbye." ) );
        e.expectMessage( containsString( "VM crash or System.exit called?" ) );

        Class<?>[] types = {Object.class, PropertiesWrapper.class, ForkClient.class, SurefireProperties.class,
            int.class, AbstractCommandReader.class, ForkNodeFactory.class, boolean.class};
        TestProvidingInputStream testProvidingInputStream = new TestProvidingInputStream( new ArrayDeque<String>() );
        invokeMethod( forkStarter, "fork", types, null,
            new PropertiesWrapper( Collections.<String, String>emptyMap() ),
            new ForkClient( reporterFactory, null, 1 ),
            new SurefireProperties(), 1, testProvidingInputStream, new LegacyForkNodeFactory(), true );
        testProvidingInputStream.close();
    }

    @Test
    public void processShouldWaitForAck() throws Exception
    {
        ReporterConfiguration reporterConfiguration = new ReporterConfiguration( tmp, true );

        ProviderConfiguration providerConfiguration = mock( ProviderConfiguration.class );
        when( providerConfiguration.getReporterConfiguration() )
            .thenReturn( reporterConfiguration );
        when( providerConfiguration.getShutdown() )
            .thenReturn( Shutdown.EXIT );

        StartupConfiguration startupConfiguration = mock( StartupConfiguration.class );
        when( startupConfiguration.getClasspathConfiguration() )
            .thenReturn( new ClasspathConfig() );
        when( startupConfiguration.getClassLoaderConfiguration() )
            .thenReturn( new ClassLoaderConfiguration( false, false ) );
        when( startupConfiguration.getProviderClassName() )
            .thenReturn( MainClass.class.getName() );

        ForkConfiguration forkConfiguration = mock( ForkConfiguration.class );
        when( forkConfiguration.getWorkingDirectory() )
            .thenReturn( tmp );
        when( forkConfiguration.getTempDirectory() )
            .thenReturn( tmp );
        when( forkConfiguration.getPluginPlatform() )
            .thenReturn( new Platform() );
        OutputStreamFlushableCommandline cli = new OutputStreamFlushableCommandline();
        cli.setWorkingDirectory( tmp );
        cli.setExecutable( System.getProperty( "java.home" ) + "/bin/java" );
        cli.createArg().setLine( "-jar" );
        cli.createArg().setLine( "surefirebooter.jar" );
        when( forkConfiguration.createCommandLine( eq( startupConfiguration ), eq( 1 ), eq( tmp ) ) )
            .thenReturn( cli );

        StartupReportConfiguration startupReportConfiguration = new StartupReportConfiguration( true, true, null,
            false, tmp, true, "", null, false, 0, null, null, true, null, null, null );

        ConsoleLogger logger = mock( ConsoleLogger.class );

        ForkStarter forkStarter = new ForkStarter( providerConfiguration, startupConfiguration, forkConfiguration,
            0, startupReportConfiguration, logger );

        DefaultReporterFactory reporterFactory = new DefaultReporterFactory( startupReportConfiguration, logger, 1 );

        Class<?>[] types = {Object.class, PropertiesWrapper.class, ForkClient.class, SurefireProperties.class,
            int.class, AbstractCommandReader.class, ForkNodeFactory.class, boolean.class};
        TestLessInputStream testLessInputStream = new TestLessInputStreamBuilder().build();
        invokeMethod( forkStarter, "fork", types, null,
            new PropertiesWrapper( Collections.<String, String>emptyMap() ),
            new ForkClient( reporterFactory, testLessInputStream, 1 ),
            new SurefireProperties(), 1, testLessInputStream, new LegacyForkNodeFactory(), true );
        testLessInputStream.close();
    }

    private static class ClasspathConfig extends AbstractPathConfiguration
    {
        ClasspathConfig()
        {
            this( Classpath.emptyClasspath(), false, false );
        }

        private ClasspathConfig( Classpath surefireClasspathUrls, boolean enableAssertions, boolean childDelegation )
        {
            super( surefireClasspathUrls, enableAssertions, childDelegation );
        }

        @Override
        public Classpath getTestClasspath()
        {
            return Classpath.emptyClasspath();
        }

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

        @Override
        public boolean isClassPathConfig()
        {
            return true;
        }

        @Override
        protected Classpath getInprocClasspath()
        {
            return Classpath.emptyClasspath();
        }
    }
}
