/**
 * Copyright (c) 2009 Capgemini Sud, 2009-2012 EBM WebSourcing, 2012-2022 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.plugin.jbiplugin;

import java.io.File;

import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.embedder.MavenEmbedder;
import org.apache.maven.embedder.MavenEmbedderConsoleLogger;
import org.apache.maven.embedder.MavenEmbedderLogger;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.settings.MavenSettingsBuilder;
import org.junit.Before;
import org.ow2.petals.plugin.jbiplugin.environement.GlobalUnitTestEnvironnement;

/**
 * Abstract class of unit test of the petals-maven-plugin.
 * @author Christophe DENEUX - Capgemini Sud
 */
public abstract class JBIAbstractTestMojo extends AbstractMojoTestCase {

    protected MavenProjectBuilder mavenProjectBuilder;

    protected ArtifactResolver mavenArtifactResolver;

    protected ArtifactFactory mavenArtifactFactory;

    protected MavenSettingsBuilder mavenSettingsBuilder;

    protected MavenEmbedder mavenEmbedder = new MavenEmbedder();

    private static final String DEBUGMODE_PROP_NAME = "DEBUG_MODE";

    /**
     * <p>
     * Flag to set the Maven embedder in debug mode (ie. Maven option '
     * <code>-X</code>').
     * </p>
     * <p>
     * It's value is driven by the system environment variable 'DEBUG_MODE' (ex:
     * <code>export DEBUG_MODE=true</code>). Default value is <code>false</code>.
     * </p>
     * <p>
     * To execute unit tests in debug mode:
     * </p>
     * <ul>
     * <li>from the command line, execute the following shell command before
     * launching the test through Maven:<br>
     * 
     * <pre>
     * export DEBUG_MODE=true
     * </pre>
     * 
     * </li>
     * <li>
     * from Eclipse, just add the environment variable to the environment of
     * your run configuration (Run Configurations/Environment).</li>
     * </ul>
     */
    // We use a system environment variable instead of a system property because
    // a system property is not propagated from the command line to the unit
    // tests through the maven-surefire-plugin.
    protected boolean debugMode;

    /**
     * @see junit.framework.TestCase#setUp()
     */
    @Before
    public void setUp() throws Exception {

        // required for mojo lookups to work and Plexus container initialization
        super.setUp();

        // Set the unit test environment
        this.debugMode = Boolean.valueOf(System.getenv(DEBUGMODE_PROP_NAME));

        this.mavenProjectBuilder = (MavenProjectBuilder) this.getContainer().lookup(
                MavenProjectBuilder.ROLE);

        this.mavenArtifactResolver = (ArtifactResolver) this.getContainer()
        .lookup(ArtifactResolver.ROLE);

        this.mavenArtifactFactory = (ArtifactFactory) this.getContainer().lookup(ArtifactFactory.ROLE);

        this.mavenSettingsBuilder = (MavenSettingsBuilder) this.getContainer().lookup(
                MavenSettingsBuilder.ROLE);

        // Maven Embedder to execute different standard goals
        this.mavenEmbedder.setClassLoader(Thread.currentThread().getContextClassLoader());
        this.mavenEmbedder.setLogger(new MavenEmbedderConsoleLogger());
        if (this.debugMode) {
            this.mavenEmbedder.getLogger().setThreshold(MavenEmbedderLogger.LEVEL_DEBUG);
        }
        this.mavenEmbedder.start();
    }

    /**
     * <p>
     * Construct a goal 'jbi-package' associated to a POM file.
     * </p>
     * <p>
     * The configuration of the generated goal is:
     * </p>
     * <ul>
     * <li><code>verbose</code> = true</li>
     * <li><code>jbiName</code> = ${project.artifactId}-${project.version}</li>
     * <li><code>jbiDirectory</code> = 'PROJECT_HOME'/src/main/jbi</li>
     * <li><code>updateJBIXml</code> = true</li>
     * <li><code>componentNameMapping</code> = ${artifactId}</li>
     * <li><code>serviceAssemblyNameMapping</code> = ${artifactId}-${version}</li>
     * <li><code>serviceUnitNameMappingInSA</code> = ${artifactId}-${version}</li>
     * <li><code>isDeployableServiceUnit</code> = false</li>
     * <li>
     * </ul>
     * 
     * @param pomXml
     *            The POM file in which the petals-maven-plugin is configure
     * @return The goal 'jbi-package'
     * @throws Exception
     */
    protected JBIPackageMojo getPackageMojo(final File pomXml) throws Exception {

        final JBIPackageMojo mojo = (JBIPackageMojo) this.lookupMojo("jbi-package", pomXml);
        final MavenProject componentProject = this.mavenEmbedder
        .readProjectWithDependencies(pomXml);

        mojo.mavenProjectBuilder = this.mavenProjectBuilder;
        mojo.artifactResolver = this.mavenArtifactResolver;
        mojo.artifactFactory = this.mavenArtifactFactory;
        mojo.localRepository = this.mavenEmbedder.createLocalRepository(this.mavenSettingsBuilder
                .buildSettings(true));

        mojo.toExcludes = "foo";
        mojo.verbose = true;
        mojo.project = componentProject;
        // mojo.projectArtifact = new ArtifactStub();
        mojo.projectArtifact = componentProject.getArtifact();
        mojo.jbiName = componentProject.getArtifactId() + "-" + componentProject.getVersion();
        mojo.jbiDirectory = new File(new File(
                GlobalUnitTestEnvironnement.PACKAGE_UNIT_TESTS_SRC_HOME, componentProject
                .getArtifactId()), "/src/main/jbi");
        mojo.outputDirectory = new File(new File(GlobalUnitTestEnvironnement.UNIT_TESTS_TARGET_HOME,
                componentProject.getArtifactId()), "target");
        mojo.updateJBIXml = true;
        mojo.componentNameMapping = "${artifactId}";
        mojo.serviceAssemblyNameMapping = "${artifactId}-${version}";
        mojo.serviceUnitNameMappingInSA = "${artifactId}-${version}";
        mojo.isDeployableServiceUnit = false;

        return mojo;

    }

    /**
     * <p>
     * Construct a goal 'jbi-package' associated to a POM file.
     * </p>
     * <p>
     * The configuration of the generated goal is:
     * </p>
     * <ul>
     * <li><code>verbose</code> = true</li>
     * <li><code>jbiName</code> = ${project.artifactId}-${project.version}</li>
     * <li><code>jbiDirectory</code> = 'PROJECT_HOME'/src/main/jbi</li>
     * <li>
     * </ul>
     * 
     * @param pomXml
     *            The POM file in which the petals-maven-plugin is configure
     * @return The goal 'jbi-package'
     * @throws Exception
     */
    protected JBIValidateMojo getValidateMojo(final File pomXml) throws Exception {

        final JBIValidateMojo mojo = (JBIValidateMojo) this.lookupMojo("jbi-validate", pomXml);
        final MavenProject componentProject = this.mavenEmbedder.readProjectWithDependencies(pomXml);

        mojo.mavenProjectBuilder = this.mavenProjectBuilder;
        mojo.artifactResolver = this.mavenArtifactResolver;
        mojo.artifactFactory = this.mavenArtifactFactory;
        mojo.localRepository = this.mavenEmbedder.createLocalRepository(this.mavenSettingsBuilder.buildSettings(true));

        mojo.verbose = true;
        mojo.project = componentProject;
        // mojo.projectArtifact = new ArtifactStub();
        mojo.projectArtifact = componentProject.getArtifact();
        mojo.jbiName = componentProject.getArtifactId() + "-" + componentProject.getVersion();
        mojo.jbiDirectory = new File(
                new File(GlobalUnitTestEnvironnement.PACKAGE_UNIT_TESTS_SRC_HOME, componentProject.getArtifactId()),
                "/src/main/jbi");
        mojo.outputDirectory = new File(
                new File(GlobalUnitTestEnvironnement.UNIT_TESTS_TARGET_HOME, componentProject.getArtifactId()),
                "target");

        return mojo;

    }
    
    protected JBIPackageMojo getPackageMojo(File pomXml, String goal) throws Exception {
        final JBIPackageMojo mojo = (JBIPackageMojo) this.lookupMojo(goal, pomXml);
        final MavenProject componentProject = this.mavenEmbedder
        .readProjectWithDependencies(pomXml);

        mojo.mavenProjectBuilder = this.mavenProjectBuilder;
        mojo.artifactResolver = this.mavenArtifactResolver;
        mojo.artifactFactory = this.mavenArtifactFactory;
        mojo.localRepository = this.mavenEmbedder.createLocalRepository(this.mavenSettingsBuilder
                .buildSettings(true));

        mojo.toExcludes = "foo";
        mojo.verbose = true;
        mojo.project = componentProject;
        // mojo.projectArtifact = new ArtifactStub();
        mojo.projectArtifact = componentProject.getArtifact();
        mojo.jbiName = componentProject.getArtifactId() + "-" + componentProject.getVersion();
        mojo.jbiDirectory = new File(new File(
                GlobalUnitTestEnvironnement.PACKAGE_UNIT_TESTS_SRC_HOME, componentProject
                .getArtifactId()), "/src/main/jbi");
        mojo.outputDirectory = new File(new File(GlobalUnitTestEnvironnement.UNIT_TESTS_TARGET_HOME,
                componentProject.getArtifactId()), "target");
        mojo.updateJBIXml = true;
        mojo.componentNameMapping = "${artifactId}";

        return mojo;
    }
}
