package org.apache.maven.archetype.mojos;

/*
 * 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.archetype.ArchetypeCreationRequest;
import org.apache.maven.archetype.ArchetypeCreationResult;
import org.apache.maven.archetype.ArchetypeManager;
import org.apache.maven.archetype.common.Constants;
import org.apache.maven.archetype.ui.creation.ArchetypeCreationConfigurator;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.PropertyUtils;
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
 * <p>
 * Creates an archetype project from the current project.
 * </p>
 * <p>
 * This goal reads your source and resource files, the values of its parameters,
 * and properties you specify in a <code>.property</code> file, and uses them to
 * create a Maven archetype project using the maven-archetype packaging.
 * If you build the resulting project, it will create the archetype. You can then
 * use this archetype to create new projects that resemble the original.
 * </p>
 * <p>
 * The maven-archetype-plugin uses Velocity to expand template files, and this documentation
 * talks about 'Velocity Properties', which are values substituted into Velocity templates.
 * See <a href="http://velocity.apache.org/engine/devel/user-guide.html">The Velocity User's Guide</a>
 * for more information.
 * </p>
 * <p>
 * This goal modifies the text of the files of the current project to form the Velocity template files
 * that make up the archetype.
 * </p>
 * <dl>
 * <dt>GAV</dt><dd>The GAV values for the current project are replaced by properties: groupId, artifactId, and version.
 * The user chooses new values for these when generating a project from the archetype.</dd>
 * <dt>package</dt><dd>All the files under one specified Java (or cognate) package are relocated to a project
 * that the user chooses when generating a project. References to the class name are replaced by a property reference. For
 * example, if the current project's sources are in the package <code>org.apache.saltedpeanuts</code>, then
 * any example of the string <code>org.apache.saltedpeanuts</code> is replaced with the Velocity property
 * reference <code>${packageName}</code>. When the user generates a project, this is in turn replaced by
 * his or her choice of a package.
 * </dd>
 * <dt>custom properties</dt><dd>You may identify additional strings that should be replaced by parameters.
 * To add custom properties, you must use the <code>propertyFile</code> parameter to specify a property file.
 * See the documentation for <code>propertyFile</code> for the details.
 * </dd>
 * <dt>integration tests</dt><dd>You may also specify a set of integration tests to be executed right after
 * you create archetype from the project. Each test consists of a separate folder under src/it/projects folder and
 * in there you specify <code>archetype.properties</code>, <code>goal.txt</code> and <code>verify.groovy</code> files.
 * The <code>archetype.properties</code> file is the file used to generate a new project from the newly created archetype
 * and the <code>goal.txt</code> a single-line file to specify the maven goal to invoke after generation of the test-project.
 * Finally the <code>verify.groovy</code> is a groovy file that you can use to specify your assertions on the generated project.
 * </dd>
 * </dl>
 * <p>
 * Note that you may need to edit the results of this goal. This goal has no way to exclude unwanted files,
 * or add copyright notices to the Velocity templates, or add more complex elements to the archetype metadata file.
 * </p>
 * <p>
 * This goal also generates a simple integration-test that exercises the generated archetype.
 * </p>
 *
 * @author rafale
 */
@Mojo( name = "create-from-project", requiresProject = true, aggregator = true )
@Execute( phase = LifecyclePhase.GENERATE_SOURCES )
public class CreateArchetypeFromProjectMojo
    extends AbstractMojo
{

    @Component
    private ArchetypeCreationConfigurator configurator;

    /**
     * Enable the interactive mode to define the archetype from the project.
     */
    @Parameter( property = "interactive", defaultValue = "false" )
    private boolean interactive;

    @Component
    private ArchetypeManager manager;

    /**
     * File file names which are checked for project's text files (vs binary files).
     */
    @Parameter( property = "archetype.filteredFileNames" )
    private String archetypeFilteredFileNames;

    /**
     * File extensions which are checked for project's text files (vs binary files).
     */
    @Parameter( property = "archetype.filteredExtentions" )
    private String archetypeFilteredExtentions;

    /**
     * Directory names which are checked for project's sources main package.
     */
    @Parameter( property = "archetype.languages" )
    private String archetypeLanguages;

    /**
     * Velocity templates encoding.
     */
    @Parameter( property = "archetype.encoding", defaultValue = "UTF-8" )
    private String defaultEncoding;

    /**
     * Create a partial archetype.
     */
    @Parameter( property = "archetype.partialArchetype" )
    private boolean partialArchetype = false;

    /**
     * Create pom's velocity templates with CDATA preservation. This uses the <code>String.replaceAll()</code>
     * method and risks to have some overly replacement capabilities (beware of '1.0' value).
     */
    @Parameter( property = "archetype.preserveCData" )
    private boolean preserveCData = false;

    @Parameter( defaultValue = "${localRepository}", readonly = true )
    private ArtifactRepository localRepository;

    /**
     * POMs in archetype are created with their initial parent.
     * This property is ignored when preserveCData is true.
     */
    @Parameter( property = "archetype.keepParent" )
    private boolean keepParent = true;

    /**
     * The Maven project to create an archetype from.
     */
    @Parameter( defaultValue = "${project}", readonly = true, required = true )
    private MavenProject project;

    /**
     * The property file that holds the plugin configuration. If this is provided, then
     * the plugin reads properties from here. The properties in here can be standard
     * properties listed below or custom properties for this archetype. The standard properties
     * are below. Several of them overlap parameters of this goal; it's better to just
     * set the parameter.
     * <p/>
     * <dl><dt>package</dt><dd>See the packageName parameter.</dd>
     * <dt>archetype.languages</dt><dd>See the archetypeLanguages parameter.</dd>
     * <dt>groupId</dt><dd>The default groupId of the generated project.</dd>
     * <dt>artifactId</dt><dd>The default artifactId of the generated project.</dd>
     * <dt>version</dt><dd>The default version of the generated project.</dd>
     * <dt>excludePatterns</dt><dd>A comma-separated list of paths that will not be included in the resulting
     * archetype.</dd>
     * <dt>archetype.filteredExtensions</dt><dd>See the filteredExensions parameter.</dd>
     * </dl>
     * <strong>Custom Properties</strong>
     * <p>
     * Custom properties allow you to replace some constant values in the project's files
     * with Velocity macro references. When a user generates a project from your archetype
     * he or she gets the opportunity to replace the value from the source project.
     * </p>
     * <p>
     * Custom property names <strong>may not contain the '.' character</strong>.
     * </p>
     * <p>
     * For example, if you include a line like the following in your property file:
     * <pre>cxf-version=2.5.1-SNAPSHOT</pre>
     * the plugin will search your files for the <code>2.5.1-SNAPSHOT</code> string and
     * replace them with references to a velocity macro <code>cxf-version</cpde>. It will
     * then list <code>cxf-version</code> as a <code>requiredProperty</code> in the
     * <code>archetype-metadata.xml</code>, with <code>2.5.1-SNAPSHOT</code> as the default value.
     * </p>
     */
    @Parameter( defaultValue = "archetype.properties", property = "archetype.properties" )
    private File propertyFile;

    /**
     * The property telling which phase to call on the generated archetype.
     * Interesting values are: <code>package</code>, <code>integration-test</code>, <code>install</code> and <code>deploy</code>.
     */
    @Parameter( property = "archetype.postPhase", defaultValue = "package" )
    private String archetypePostPhase;

    /**
     * The directory where the archetype should be created.
     */
    @Parameter( defaultValue = "${project.build.directory}/generated-sources/archetype" )
    private File outputDirectory;

    @Parameter( property = "testMode" )
    private boolean testMode;

    /**
     * The package name for Java source files to be incorporated in the archetype and
     * and relocated to the package that the user selects.
     */
    @Parameter( property = "packageName" )
    private String packageName; //Find a better way to resolve the package!!! enforce usage of the configurator

    @Parameter( defaultValue = "${session}", readonly = true, required = true )
    private MavenSession session;

//    @Parameter( defaultValue = "${session.settings}", readonly = true, required = true )
//    private File settingsXml;

    @Override
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        Properties executionProperties = session.getExecutionProperties();
        try
        {
            if ( propertyFile != null )
            {
                propertyFile.getParentFile().mkdirs();
            }

            List<String> languages = getLanguages( archetypeLanguages, propertyFile );

            Properties properties =
                configurator.configureArchetypeCreation( project, Boolean.valueOf( interactive ), executionProperties,
                                                         propertyFile, languages );

            List<String> filteredFileNames = getFilteredFileNames( archetypeFilteredFileNames, propertyFile );
            List<String> filteredFileExtensions = getFilteredExtensions( archetypeFilteredExtentions, propertyFile );

            ArchetypeCreationRequest request =
                new ArchetypeCreationRequest().setDefaultEncoding( defaultEncoding ).setProject( project )
                /* Used when in interactive mode */.setProperties( properties ).setLanguages( languages )
                                              .setFilteredFileNames( filteredFileNames )
                /* Should be refactored to use some ant patterns */.setFilteredFileExtensions( filteredFileExtensions )
                /* This should be correctly handled */.setPreserveCData( preserveCData ).setKeepParent(
                    keepParent ).setPartialArchetype( partialArchetype )
                .setLocalRepository( localRepository ).setProjectBuildingRequest( session.getProjectBuildingRequest() )
                /* this should be resolved and asked for user to verify */.setPackageName( packageName ).setPostPhase(
                    archetypePostPhase ).setOutputDirectory( outputDirectory ).setSettingsFile( session.getRequest().getUserSettingsFile() );

            ArchetypeCreationResult result = manager.createArchetypeFromProject( request );

            if ( result.getCause() != null )
            {
                throw new MojoFailureException( result.getCause(), result.getCause().getMessage(),
                                                result.getCause().getMessage() );
            }

            getLog().info( "Archetype project created in " + outputDirectory );

            if ( testMode )
            {
                // Now here a properties file would be useful to write so that we could automate
                // some functional tests where we string together an:
                //
                // archetype create from project -> deploy it into a test repo
                // project create from archetype -> use the repository we deployed to archetype to
                // generate
                // test the output
                //
                // This of course would be strung together from the outside.
            }

        }
        catch ( MojoFailureException ex )
        {
            throw ex;
        }
        catch ( Exception ex )
        {
            throw new MojoFailureException( ex, ex.getMessage(), ex.getMessage() );
        }
    }

    private List<String> getFilteredFileNames( String archetypeFilteredFileNames, File propertyFile ) throws IOException
    {
        List<String> filteredFileNames = new ArrayList<>();

        if ( StringUtils.isNotEmpty( archetypeFilteredFileNames ) )
        {
            filteredFileNames.addAll( Arrays.asList( StringUtils.split( archetypeFilteredFileNames, "," ) ) );

            getLog().debug( "Found in command line fileNames = " + filteredFileNames );
        }

        if ( filteredFileNames.isEmpty() && propertyFile != null && propertyFile.exists() )
        {
            Properties properties = PropertyUtils.loadProperties( propertyFile );

            String fileNames = properties.getProperty( Constants.ARCHETYPE_FILTERED_FILENAMES );
            if ( StringUtils.isNotEmpty( fileNames ) )
            {
                filteredFileNames.addAll( Arrays.asList( fileNames.split( "," ) ) );
            }

            getLog().debug( "Found in propertyFile " + propertyFile.getName() + " fileNames = " + filteredFileNames );
        }

        return filteredFileNames;
    }

    private List<String> getFilteredExtensions( String archetypeFilteredExtentions, File propertyFile ) throws IOException
    {
        List<String> filteredExtensions = new ArrayList<>();

        if ( StringUtils.isNotEmpty( archetypeFilteredExtentions ) )
        {
            filteredExtensions.addAll( Arrays.asList( StringUtils.split( archetypeFilteredExtentions, "," ) ) );

            getLog().debug( "Found in command line extensions = " + filteredExtensions );
        }

        if ( filteredExtensions.isEmpty() && propertyFile != null && propertyFile.exists() )
        {
            Properties properties = PropertyUtils.loadProperties( propertyFile );

            String extensions = properties.getProperty( Constants.ARCHETYPE_FILTERED_EXTENSIONS );
            if ( StringUtils.isNotEmpty( extensions ) )
            {
                filteredExtensions.addAll( Arrays.asList( StringUtils.split( extensions, "," ) ) );
            }

            getLog().debug( "Found in propertyFile " + propertyFile.getName() + " extensions = " + filteredExtensions );
        }

        if ( filteredExtensions.isEmpty() )
        {
            filteredExtensions.addAll( Constants.DEFAULT_FILTERED_EXTENSIONS );

            getLog().debug( "Using default extensions = " + filteredExtensions );
        }

        return filteredExtensions;
    }

    private List<String> getLanguages( String archetypeLanguages, File propertyFile ) throws IOException
    {
        List<String> resultingLanguages = new ArrayList<>();

        if ( StringUtils.isNotEmpty( archetypeLanguages ) )
        {
            resultingLanguages.addAll( Arrays.asList( StringUtils.split( archetypeLanguages, "," ) ) );

            getLog().debug( "Found in command line languages = " + resultingLanguages );
        }

        if ( resultingLanguages.isEmpty() && propertyFile != null && propertyFile.exists() )
        {
            Properties properties = PropertyUtils.loadProperties( propertyFile );

            String languages = properties.getProperty( Constants.ARCHETYPE_LANGUAGES );
            if ( StringUtils.isNotEmpty( languages ) )
            {
                resultingLanguages.addAll( Arrays.asList( StringUtils.split( languages, "," ) ) );
            }

            getLog().debug( "Found in propertyFile " + propertyFile.getName() + " languages = " + resultingLanguages );
        }

        if ( resultingLanguages.isEmpty() )
        {
            resultingLanguages.addAll( Constants.DEFAULT_LANGUAGES );

            getLog().debug( "Using default languages = " + resultingLanguages );
        }

        return resultingLanguages;
    }
}
