package org.apache.maven.plugin.compiler;

/*
 * 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 static org.mockito.ArgumentMatchers.startsWith;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.compiler.stubs.CompilerManagerStub;
import org.apache.maven.plugin.compiler.stubs.DebugEnabledLog;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
import org.apache.maven.plugin.testing.stubs.ArtifactStub;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.languages.java.version.JavaVersion;

public class CompilerMojoTestCase
    extends AbstractMojoTestCase
{
    
    private String source = AbstractCompilerMojo.DEFAULT_SOURCE;

    private String target = AbstractCompilerMojo.DEFAULT_TARGET;
    
    @Override
    protected void setUp()
        throws Exception
    {
        super.setUp();
        
        String javaSpec = System.getProperty( "java.specification.version" );
        // It is needed to set target/source to JDK 7 for JDK12+
        // because this is the lowest version which is supported by those JDK's.
        // The default source/target "6" is not supported anymore.
        if ( JavaVersion.parse( javaSpec ).isAtLeast( "12" ) )
        {
            source = "7";
            target = "7";
        }
    }
    
    /**
     * tests the ability of the plugin to compile a basic file
     *
     * @throws Exception
     */
    public void testCompilerBasic()
        throws Exception
    {
        CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-basic-test/plugin-config.xml" );
        
        Log log = mock( Log.class );
        
        compileMojo.setLog( log );
        
        compileMojo.execute();

        File testClass = new File( compileMojo.getOutputDirectory(), "TestCompile0.class" );

        assertTrue( testClass.exists() );

        TestCompilerMojo testCompileMojo =
            getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-basic-test/plugin-config.xml" );

        testCompileMojo.execute();

        Artifact projectArtifact = (Artifact) getVariableValueFromObject( compileMojo, "projectArtifact" );
        assertNotNull( "MCOMPILER-94: artifact file should only be null if there is nothing to compile",
                       projectArtifact.getFile() );

        testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile0Test.class" );
        
        verify( log ).warn( startsWith( "No explicit value set for target or release!" ) );

        assertTrue( testClass.exists() );
    }
    
    public void testCompilerBasicSourceTarget()
                    throws Exception
    {
        CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-basic-sourcetarget/plugin-config.xml" );
        
        Log log = mock( Log.class );
        
        compileMojo.setLog( log );
        
        compileMojo.execute();
        
        verify( log, never() ).warn( startsWith( "No explicit value set for target or release!" ) );
    }

    /**
     * tests the ability of the plugin to respond to empty source
     *
     * @throws Exception
     */
    public void testCompilerEmptySource()
        throws Exception
    {
        CompilerMojo compileMojo =
            getCompilerMojo( "target/test-classes/unit/compiler-empty-source-test/plugin-config.xml" );

        compileMojo.execute();

        assertFalse( compileMojo.getOutputDirectory().exists() );

        Artifact projectArtifact = (Artifact) getVariableValueFromObject( compileMojo, "projectArtifact" );
        assertNull( "MCOMPILER-94: artifact file should be null if there is nothing to compile",
                    projectArtifact.getFile() );

        TestCompilerMojo testCompileMojo =
            getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-empty-source-test/plugin-config.xml" );

        testCompileMojo.execute();

        assertFalse( testCompileMojo.getOutputDirectory().exists() );
    }

    /**
     * tests the ability of the plugin to respond to includes and excludes correctly
     *
     * @throws Exception
     */
    public void testCompilerIncludesExcludes()
        throws Exception
    {
        CompilerMojo compileMojo =
            getCompilerMojo( "target/test-classes/unit/compiler-includes-excludes-test/plugin-config.xml" );

        Set<String> includes = new HashSet<>();
        includes.add( "**/TestCompile4*.java" );
        setVariableValueToObject( compileMojo, "includes", includes );

        Set<String> excludes = new HashSet<>();
        excludes.add( "**/TestCompile2*.java" );
        excludes.add( "**/TestCompile3*.java" );
        setVariableValueToObject( compileMojo, "excludes", excludes );

        compileMojo.execute();

        File testClass = new File( compileMojo.getOutputDirectory(), "TestCompile2.class" );
        assertFalse( testClass.exists() );

        testClass = new File( compileMojo.getOutputDirectory(), "TestCompile3.class" );
        assertFalse( testClass.exists() );

        testClass = new File( compileMojo.getOutputDirectory(), "TestCompile4.class" );
        assertTrue( testClass.exists() );

        TestCompilerMojo testCompileMojo = getTestCompilerMojo( compileMojo,
                                                                "target/test-classes/unit/compiler-includes-excludes-test/plugin-config.xml" );

        setVariableValueToObject( testCompileMojo, "testIncludes", includes );
        setVariableValueToObject( testCompileMojo, "testExcludes", excludes );

        testCompileMojo.execute();

        testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile2TestCase.class" );
        assertFalse( testClass.exists() );

        testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile3TestCase.class" );
        assertFalse( testClass.exists() );

        testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile4TestCase.class" );
        assertTrue( testClass.exists() );
    }

    /**
     * tests the ability of the plugin to fork and successfully compile
     *
     * @throws Exception
     */
    public void testCompilerFork()
        throws Exception
    {
        CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-fork-test/plugin-config.xml" );

        // JAVA_HOME doesn't have to be on the PATH.
        setVariableValueToObject( compileMojo, "executable",  new File( System.getenv( "JAVA_HOME" ), "bin/javac" ).getPath() );

        compileMojo.execute();

        File testClass = new File( compileMojo.getOutputDirectory(), "TestCompile1.class" );
        assertTrue( testClass.exists() );

        TestCompilerMojo testCompileMojo =
            getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-fork-test/plugin-config.xml" );

        // JAVA_HOME doesn't have to be on the PATH.
        setVariableValueToObject( testCompileMojo, "executable",  new File( System.getenv( "JAVA_HOME" ), "bin/javac" ).getPath() );

        testCompileMojo.execute();

        testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile1TestCase.class" );
        assertTrue( testClass.exists() );
    }

    public void testOneOutputFileForAllInput()
        throws Exception
    {
        CompilerMojo compileMojo =
            getCompilerMojo( "target/test-classes/unit/compiler-one-output-file-test/plugin-config.xml" );

        setVariableValueToObject( compileMojo, "compilerManager", new CompilerManagerStub() );

        compileMojo.execute();

        File testClass = new File( compileMojo.getOutputDirectory(), "compiled.class" );
        assertTrue( testClass.exists() );

        TestCompilerMojo testCompileMojo = getTestCompilerMojo( compileMojo,
                                                                "target/test-classes/unit/compiler-one-output-file-test/plugin-config.xml" );

        setVariableValueToObject( testCompileMojo, "compilerManager", new CompilerManagerStub() );

        testCompileMojo.execute();

        testClass = new File( testCompileMojo.getOutputDirectory(), "compiled.class" );
        assertTrue( testClass.exists() );
    }

    public void testCompilerArgs()
        throws Exception
    {
        CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-args-test/plugin-config.xml" );

        setVariableValueToObject( compileMojo, "compilerManager", new CompilerManagerStub() );

        compileMojo.execute();

        File testClass = new File( compileMojo.getOutputDirectory(), "compiled.class" );
        assertTrue( testClass.exists() );
        assertEquals( Arrays.asList( "key1=value1","-Xlint","-my&special:param-with+chars/not>allowed_in_XML_element_names" ), compileMojo.compilerArgs );
    }

    public void testImplicitFlagNone()
        throws Exception
    {
        CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-implicit-test/plugin-config-none.xml" );

        assertEquals( "none", compileMojo.getImplicit() );
    }

    public void testImplicitFlagNotSet()
        throws Exception
    {
        CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-implicit-test/plugin-config-not-set.xml" );

        assertNull( compileMojo.getImplicit() );
    }

    public void testOneOutputFileForAllInput2()
        throws Exception
    {
        CompilerMojo compileMojo =
            getCompilerMojo( "target/test-classes/unit/compiler-one-output-file-test2/plugin-config.xml" );

        setVariableValueToObject( compileMojo, "compilerManager", new CompilerManagerStub() );

        Set<String> includes = new HashSet<>();
        includes.add( "**/TestCompile4*.java" );
        setVariableValueToObject( compileMojo, "includes", includes );

        Set<String> excludes = new HashSet<>();
        excludes.add( "**/TestCompile2*.java" );
        excludes.add( "**/TestCompile3*.java" );
        setVariableValueToObject( compileMojo, "excludes", excludes );

        compileMojo.execute();

        File testClass = new File( compileMojo.getOutputDirectory(), "compiled.class" );
        assertTrue( testClass.exists() );

        TestCompilerMojo testCompileMojo = getTestCompilerMojo( compileMojo,
                                                                "target/test-classes/unit/compiler-one-output-file-test2/plugin-config.xml" );

        setVariableValueToObject( testCompileMojo, "compilerManager", new CompilerManagerStub() );
        setVariableValueToObject( testCompileMojo, "testIncludes", includes );
        setVariableValueToObject( testCompileMojo, "testExcludes", excludes );

        testCompileMojo.execute();

        testClass = new File( testCompileMojo.getOutputDirectory(), "compiled.class" );
        assertTrue( testClass.exists() );
    }

    public void testCompileFailure()
        throws Exception
    {
        CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-fail-test/plugin-config.xml" );

        setVariableValueToObject( compileMojo, "compilerManager", new CompilerManagerStub( true ) );

        try
        {
            compileMojo.execute();

            fail( "Should throw an exception" );
        }
        catch ( CompilationFailureException e )
        {
            //expected
        }
    }

    public void testCompileFailOnError()
        throws Exception
    {
        CompilerMojo compileMojo =
            getCompilerMojo( "target/test-classes/unit/compiler-failonerror-test/plugin-config.xml" );

        setVariableValueToObject( compileMojo, "compilerManager", new CompilerManagerStub( true ) );

        try
        {
            compileMojo.execute();
            assertTrue( true );
        }
        catch ( CompilationFailureException e )
        {
            fail( "The compilation error should have been consumed because failOnError = false" );
        }
    }
    
    /**
     * Tests that setting 'skipMain' to true skips compilation of the main Java source files, but that test Java source
     * files are still compiled.
     * @throws Exception
     */
    public void testCompileSkipMain()
        throws Exception
    {
        CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-skip-main/plugin-config.xml" );
        setVariableValueToObject( compileMojo, "skipMain", true );
        compileMojo.execute();
        File testClass = new File( compileMojo.getOutputDirectory(), "TestSkipMainCompile0.class" );
        assertFalse( testClass.exists() );

        TestCompilerMojo testCompileMojo =
            getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-skip-main/plugin-config.xml" );
        testCompileMojo.execute();
        testClass = new File( testCompileMojo.getOutputDirectory(), "TestSkipMainCompile0Test.class" );
        assertTrue( testClass.exists() );
    }
    
    /**
     * Tests that setting 'skip' to true skips compilation of the test Java source files, but that main Java source
     * files are still compiled.
     * @throws Exception
     */
    public void testCompileSkipTest()
        throws Exception
    {
        CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-skip-test/plugin-config.xml" );
        compileMojo.execute();
        File testClass = new File( compileMojo.getOutputDirectory(), "TestSkipTestCompile0.class" );
        assertTrue( testClass.exists() );

        TestCompilerMojo testCompileMojo =
            getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-skip-test/plugin-config.xml" );
        setVariableValueToObject( testCompileMojo, "skip", true );
        testCompileMojo.execute();
        testClass = new File( testCompileMojo.getOutputDirectory(), "TestSkipTestCompile0Test.class" );
        assertFalse( testClass.exists() );
    }

    private CompilerMojo getCompilerMojo( String pomXml )
        throws Exception
    {
        File testPom = new File( getBasedir(), pomXml );

        CompilerMojo mojo = (CompilerMojo) lookupMojo( "compile", testPom );

        setVariableValueToObject( mojo, "log", new DebugEnabledLog() );
        setVariableValueToObject( mojo, "projectArtifact", new ArtifactStub() );
        setVariableValueToObject( mojo, "compilePath", Collections.EMPTY_LIST );
        setVariableValueToObject( mojo, "session", getMockMavenSession() );
        setVariableValueToObject( mojo, "project", getMockMavenProject() );
        setVariableValueToObject( mojo, "mojoExecution", getMockMojoExecution() );
        setVariableValueToObject( mojo, "source", source );
        setVariableValueToObject( mojo, "target", target );

        return mojo;
    }

    private TestCompilerMojo getTestCompilerMojo( CompilerMojo compilerMojo, String pomXml )
        throws Exception
    {
        File testPom = new File( getBasedir(), pomXml );

        TestCompilerMojo mojo = (TestCompilerMojo) lookupMojo( "testCompile", testPom );

        setVariableValueToObject( mojo, "log", new DebugEnabledLog() );

        File buildDir = (File) getVariableValueFromObject( compilerMojo, "buildDirectory" );
        File testClassesDir = new File( buildDir, "test-classes" );
        setVariableValueToObject( mojo, "outputDirectory", testClassesDir );

        List<String> testClasspathList = new ArrayList<>();
        
        Artifact junitArtifact = mock( Artifact.class );
        ArtifactHandler handler = mock( ArtifactHandler.class );
        when( handler.isAddedToClasspath() ).thenReturn( true );
        when( junitArtifact.getArtifactHandler() ).thenReturn( handler );

        File artifactFile;
        String localRepository = System.getProperty( "localRepository" );
        if ( localRepository != null )
        {
            artifactFile = new File( localRepository, "junit/junit/3.8.1/junit-3.8.1.jar" );
        }
        else
        {
            // for IDE
            String junitURI = org.junit.Test.class.getResource( "Test.class" ).toURI().toString();
            junitURI = junitURI.substring( "jar:".length(), junitURI.indexOf( '!' ) );
            artifactFile = new File( URI.create( junitURI ) );
        }
        when ( junitArtifact.getFile() ).thenReturn( artifactFile );
        
        testClasspathList.add( artifactFile.getAbsolutePath() );
        testClasspathList.add( compilerMojo.getOutputDirectory().getPath() );

        String testSourceRoot = testPom.getParent() + "/src/test/java";
        setVariableValueToObject( mojo, "compileSourceRoots", Collections.singletonList( testSourceRoot ) );

        MavenProject project = getMockMavenProject();
        project.setFile( testPom );
        project.addCompileSourceRoot("/src/main/java" );
        project.setArtifacts( Collections.singleton( junitArtifact )  );
        project.getBuild().setOutputDirectory( new File( buildDir, "classes" ).getAbsolutePath() );
        setVariableValueToObject( mojo, "project", project );
        setVariableValueToObject( mojo, "testPath", testClasspathList );
        setVariableValueToObject( mojo, "session", getMockMavenSession() );
        setVariableValueToObject( mojo, "mojoExecution", getMockMojoExecution() );
        setVariableValueToObject( mojo, "source", source );
        setVariableValueToObject( mojo, "target", target );

        return mojo;
    }
    
    private MavenProject getMockMavenProject()
    {
        MavenProject mp = new MavenProject();
        mp.getBuild().setDirectory( "target" );
        mp.getBuild().setOutputDirectory( "target/classes" );
        mp.getBuild().setSourceDirectory( "src/main/java" );
        mp.getBuild().setTestOutputDirectory( "target/test-classes" );
        return mp;
    }

    private MavenSession getMockMavenSession()
    {
        MavenSession session = mock( MavenSession.class );
        // when( session.getPluginContext( isA(PluginDescriptor.class), isA(MavenProject.class) ) ).thenReturn(
        // Collections.emptyMap() );
        when( session.getCurrentProject() ).thenReturn( getMockMavenProject() );
        return session;
    }

    private MojoExecution getMockMojoExecution()
    {
        MojoDescriptor md = new MojoDescriptor();
        md.setGoal( "compile" );

        MojoExecution me = new MojoExecution( md );

        PluginDescriptor pd = new PluginDescriptor();
        pd.setArtifactId( "maven-compiler-plugin" );
        md.setPluginDescriptor( pd );

        return me;
    }
}
