package org.apache.maven.plugins.resources;

/*
 * 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 java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
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.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.maven.shared.filtering.MavenResourcesExecution;
import org.apache.maven.shared.filtering.MavenResourcesFiltering;

/**
 * Copy resources for the main source code to the main output directory. Always uses the project.build.resources element
 * to specify the resources to copy.
 *
 * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
 * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
 * @author Andreas Hoheneder
 * @author William Ferguson
 */
@Mojo( name = "resources", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, requiresProject = true, threadSafe = true )
public class ResourcesMojo
        extends AbstractMojo
{

    /**
     * The character encoding to use when reading and writing filtered resources.
     */
    @Parameter( defaultValue = "${project.build.sourceEncoding}" )
    protected String encoding;

    /**
     * The character encoding to use when reading and writing filtered properties files.
     * If not specified, it will default to the value of the "encoding" parameter.
     *
     * @since 3.2.0
     */
    @Parameter
    protected String propertiesEncoding;

    /**
     * The output directory into which to copy the resources.
     */
    @Parameter( defaultValue = "${project.build.outputDirectory}", required = true )
    private File outputDirectory;

    /**
     * The list of resources we want to transfer.
     */
    @Parameter( defaultValue = "${project.resources}", required = true )
    private List<Resource> resources;

    /**
     *
     */
    @Parameter( defaultValue = "${project}", readonly = true, required = true )
    protected MavenProject project;

    /**
     * The list of additional filter properties files to be used along with System and project properties, which would
     * be used for the filtering.
     *
     * @see ResourcesMojo#filters
     * @since 2.4
     */
    @Parameter( defaultValue = "${project.build.filters}", readonly = true )
    protected List<String> buildFilters;

    /**
     * <p>
     * The list of extra filter properties files to be used along with System properties, project properties, and filter
     * properties files specified in the POM build/filters section, which should be used for the filtering during the
     * current mojo execution.</p>
     * <p>
     * Normally, these will be configured from a plugin's execution section, to provide a different set of filters for a
     * particular execution. For instance, starting in Maven 2.2.0, you have the option of configuring executions with
     * the id's <code>default-resources</code> and <code>default-testResources</code> to supply different configurations
     * for the two different types of resources. By supplying <code>extraFilters</code> configurations, you can separate
     * which filters are used for which type of resource.</p>
     */
    @Parameter
    protected List<String> filters;

    /**
     * If false, don't use the filters specified in the build/filters section of the POM when processing resources in
     * this mojo execution.
     *
     * @see ResourcesMojo#buildFilters
     * @see ResourcesMojo#filters
     * @since 2.4
     */
    @Parameter( defaultValue = "true" )
    protected boolean useBuildFilters;

    /**
     *
     */
    @Component( role = MavenResourcesFiltering.class, hint = "default" )
    protected MavenResourcesFiltering mavenResourcesFiltering;

    /**
     *
     */
    @Component( role = MavenResourcesFiltering.class )
    protected Map<String, MavenResourcesFiltering> mavenResourcesFilteringMap;

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

    /**
     * Expressions preceded with this string won't be interpolated. Anything else preceded with this string will be
     * passed through unchanged. For example {@code \${foo}} will be replaced with {@code ${foo}} but {@code \\${foo}}
     * will be replaced with {@code \\value of foo}, if this parameter has been set to the backslash.
     *
     * @since 2.3
     */
    @Parameter
    protected String escapeString;

    /**
     * Overwrite existing files even if the destination files are newer.
     *
     * @since 2.3
     */
    @Parameter( defaultValue = "false" )
    private boolean overwrite;

    /**
     * Copy any empty directories included in the Resources.
     *
     * @since 2.3
     */
    @Parameter( defaultValue = "false" )
    protected boolean includeEmptyDirs;

    /**
     * Additional file extensions to not apply filtering (already defined are : jpg, jpeg, gif, bmp, png)
     *
     * @since 2.3
     */
    @Parameter
    protected List<String> nonFilteredFileExtensions;

    /**
     * Whether to escape backslashes and colons in windows-style paths.
     *
     * @since 2.4
     */
    @Parameter( defaultValue = "true" )
    protected boolean escapeWindowsPaths;

    /**
     * <p>
     * Set of delimiters for expressions to filter within the resources. These delimiters are specified in the form
     * {@code beginToken*endToken}. If no {@code *} is given, the delimiter is assumed to be the same for start and end.
     * </p>
     * <p>
     * So, the default filtering delimiters might be specified as:
     * </p>
     *
     * <pre>
     * &lt;delimiters&gt;
     *   &lt;delimiter&gt;${*}&lt;/delimiter&gt;
     *   &lt;delimiter&gt;@&lt;/delimiter&gt;
     * &lt;/delimiters&gt;
     * </pre>
     * <p>
     * Since the {@code @} delimiter is the same on both ends, we don't need to specify {@code @*@} (though we can).
     * </p>
     *
     * @since 2.4
     */
    @Parameter
    protected LinkedHashSet<String> delimiters;

    /**
     * Use default delimiters in addition to custom delimiters, if any.
     *
     * @since 2.4
     */
    @Parameter( defaultValue = "true" )
    protected boolean useDefaultDelimiters;

    /**
     * By default files like {@code .gitignore}, {@code .cvsignore} etc. are excluded which means they will not being
     * copied. If you need them for a particular reason you can do that by settings this to {@code false}. This means
     * all files like the following will be copied.
     * <ul>
     * <li>Misc: &#42;&#42;/&#42;~, &#42;&#42;/#&#42;#, &#42;&#42;/.#&#42;, &#42;&#42;/%&#42;%, &#42;&#42;/._&#42;</li>
     * <li>CVS: &#42;&#42;/CVS, &#42;&#42;/CVS/&#42;&#42;, &#42;&#42;/.cvsignore</li>
     * <li>RCS: &#42;&#42;/RCS, &#42;&#42;/RCS/&#42;&#42;</li>
     * <li>SCCS: &#42;&#42;/SCCS, &#42;&#42;/SCCS/&#42;&#42;</li>
     * <li>VSSercer: &#42;&#42;/vssver.scc</li>
     * <li>MKS: &#42;&#42;/project.pj</li>
     * <li>SVN: &#42;&#42;/.svn, &#42;&#42;/.svn/&#42;&#42;</li>
     * <li>GNU: &#42;&#42;/.arch-ids, &#42;&#42;/.arch-ids/&#42;&#42;</li>
     * <li>Bazaar: &#42;&#42;/.bzr, &#42;&#42;/.bzr/&#42;&#42;</li>
     * <li>SurroundSCM: &#42;&#42;/.MySCMServerInfo</li>
     * <li>Mac: &#42;&#42;/.DS_Store</li>
     * <li>Serena Dimension: &#42;&#42;/.metadata, &#42;&#42;/.metadata/&#42;&#42;</li>
     * <li>Mercurial: &#42;&#42;/.hg, &#42;&#42;/.hg/&#42;&#42;</li>
     * <li>GIT: &#42;&#42;/.git, &#42;&#42;/.gitignore, &#42;&#42;/.gitattributes, &#42;&#42;/.git/&#42;&#42;</li>
     * <li>Bitkeeper: &#42;&#42;/BitKeeper, &#42;&#42;/BitKeeper/&#42;&#42;, &#42;&#42;/ChangeSet,
     * &#42;&#42;/ChangeSet/&#42;&#42;</li>
     * <li>Darcs: &#42;&#42;/_darcs, &#42;&#42;/_darcs/&#42;&#42;, &#42;&#42;/.darcsrepo,
     * &#42;&#42;/.darcsrepo/&#42;&#42;&#42;&#42;/-darcs-backup&#42;, &#42;&#42;/.darcs-temp-mail
     * </ul>
     *
     * @since 3.0.0
     */
    @Parameter( defaultValue = "true" )
    protected boolean addDefaultExcludes;

    /**
     * <p>
     * List of plexus components hint which implements
     * {@link MavenResourcesFiltering#filterResources(MavenResourcesExecution)}. They will be executed after the
     * resources copying/filtering.
     * </p>
     *
     * @since 2.4
     */
    @Parameter
    private List<String> mavenFilteringHints;

    /**
     * @since 2.4
     */
    private List<MavenResourcesFiltering> mavenFilteringComponents = new ArrayList<>();

    /**
     * stop searching endToken at the end of line
     *
     * @since 2.5
     */
    @Parameter( defaultValue = "false" )
    private boolean supportMultiLineFiltering;

    /**
     * Support filtering of filenames folders etc.
     *
     * @since 3.0.0
     */
    @Parameter( defaultValue = "false" )
    private boolean fileNameFiltering;

    /**
     * You can skip the execution of the plugin if you need to. Its use is NOT RECOMMENDED, but quite convenient on
     * occasion.
     *
     * @since 3.0.0
     */
    @Parameter( property = "maven.resources.skip", defaultValue = "false" )
    private boolean skip;

    /**
     * {@inheritDoc}
     */
    public void execute()
            throws MojoExecutionException
    {
        if ( isSkip() )
        {
            getLog().info( "Skipping the execution." );
            return;
        }

        if ( StringUtils.isBlank( encoding ) && isFilteringEnabled( getResources() ) )
        {
            getLog().warn( "File encoding has not been set, using platform encoding "
                    + System.getProperty( "file.encoding" )
                    + ". Build is platform dependent!" );
            getLog().warn( "See https://maven.apache.org/general.html#encoding-warning" );
        }

        try
        {
            List<String> combinedFilters = getCombinedFiltersList();

            MavenResourcesExecution mavenResourcesExecution =
                    new MavenResourcesExecution( getResources(), getOutputDirectory(), project, encoding,
                            combinedFilters,
                            Collections.emptyList(), session );

            mavenResourcesExecution.setEscapeWindowsPaths( escapeWindowsPaths );

            // never include project build filters in this call, since we've already accounted for the POM build filters
            // above, in getCombinedFiltersList().
            mavenResourcesExecution.setInjectProjectBuildFilters( false );

            mavenResourcesExecution.setEscapeString( escapeString );
            mavenResourcesExecution.setOverwrite( overwrite );
            mavenResourcesExecution.setIncludeEmptyDirs( includeEmptyDirs );
            mavenResourcesExecution.setSupportMultiLineFiltering( supportMultiLineFiltering );
            mavenResourcesExecution.setFilterFilenames( fileNameFiltering );
            mavenResourcesExecution.setAddDefaultExcludes( addDefaultExcludes );

            // Handle subject of MRESOURCES-99
            Properties additionalProperties = addSeveralSpecialProperties();
            mavenResourcesExecution.setAdditionalProperties( additionalProperties );

            // if these are NOT set, just use the defaults, which are '${*}' and '@'.
            mavenResourcesExecution.setDelimiters( delimiters, useDefaultDelimiters );

            // Handle MRESOURCES-171
            mavenResourcesExecution.setPropertiesEncoding( propertiesEncoding );

            if ( nonFilteredFileExtensions != null )
            {
                mavenResourcesExecution.setNonFilteredFileExtensions( nonFilteredFileExtensions );
            }
            mavenResourcesFiltering.filterResources( mavenResourcesExecution );

            executeUserFilterComponents( mavenResourcesExecution );
        }
        catch ( MavenFilteringException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
    }

    /**
     * This solves https://issues.apache.org/jira/browse/MRESOURCES-99.<br/>
     * BUT:<br/>
     * This should be done different than defining those properties a second time, cause they have already being defined
     * in Maven Model Builder (package org.apache.maven.model.interpolation) via BuildTimestampValueSource. But those
     * can't be found in the context which can be got from the maven core.<br/>
     * A solution could be to put those values into the context by Maven core so they are accessible everywhere. (I'm
     * not sure if this is a good idea). Better ideas are always welcome.
     * <p>
     * The problem at the moment is that maven core handles usage of properties and replacements in
     * the model, but does not the resource filtering which needed some of the properties.
     *
     * @return the new instance with those properties.
     */
    private Properties addSeveralSpecialProperties()
    {
        String timeStamp = new MavenBuildTimestamp().formattedTimestamp();
        Properties additionalProperties = new Properties();
        additionalProperties.put( "maven.build.timestamp", timeStamp );
        if ( project.getBasedir() != null )
        {
            additionalProperties.put( "project.baseUri", project.getBasedir().getAbsoluteFile().toURI().toString() );
        }

        return additionalProperties;
    }

    /**
     * @param mavenResourcesExecution {@link MavenResourcesExecution}
     * @throws MojoExecutionException  in case of wrong lookup.
     * @throws MavenFilteringException in case of failure.
     * @since 2.5
     */
    protected void executeUserFilterComponents( MavenResourcesExecution mavenResourcesExecution )
            throws MojoExecutionException, MavenFilteringException
    {

        if ( mavenFilteringHints != null )
        {
            for ( String hint : mavenFilteringHints )
            {
                MavenResourcesFiltering userFilterComponent = mavenResourcesFilteringMap.get( hint );
                if ( userFilterComponent != null )
                {
                    getLog().debug( "added user filter component with hint: " + hint );
                    mavenFilteringComponents.add( userFilterComponent );
                }
                else
                {
                    throw new MojoExecutionException(
                            "User filter with hint `" + hint + "` requested, but not present. Discovered filters are: "
                                    + mavenResourcesFilteringMap.keySet() );
                }
            }
        }
        else
        {
            getLog().debug( "no user filter components" );
        }

        if ( mavenFilteringComponents != null && !mavenFilteringComponents.isEmpty() )
        {
            getLog().debug( "execute user filters" );
            for ( MavenResourcesFiltering filter : mavenFilteringComponents )
            {
                filter.filterResources( mavenResourcesExecution );
            }
        }
    }

    /**
     * @return The combined filters.
     */
    protected List<String> getCombinedFiltersList()
    {
        if ( filters == null || filters.isEmpty() )
        {
            return useBuildFilters ? buildFilters : null;
        }
        else
        {
            List<String> result = new ArrayList<>();

            if ( useBuildFilters && buildFilters != null && !buildFilters.isEmpty() )
            {
                result.addAll( buildFilters );
            }

            result.addAll( filters );

            return result;
        }
    }

    /**
     * Determines whether filtering has been enabled for any resource.
     *
     * @param theResources The set of resources to check for filtering, may be <code>null</code>.
     * @return <code>true</code> if at least one resource uses filtering, <code>false</code> otherwise.
     */
    private boolean isFilteringEnabled( Collection<Resource> theResources )
    {
        if ( theResources != null )
        {
            for ( Resource resource : theResources )
            {
                if ( resource.isFiltering() )
                {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * @return {@link #resources}
     */
    public List<Resource> getResources()
    {
        return resources;
    }

    /**
     * @param resources set {@link #resources}
     */
    public void setResources( List<Resource> resources )
    {
        this.resources = resources;
    }

    /**
     * @return {@link #outputDirectory}
     */
    public File getOutputDirectory()
    {
        return outputDirectory;
    }

    /**
     * @param outputDirectory the output folder.
     */
    public void setOutputDirectory( File outputDirectory )
    {
        this.outputDirectory = outputDirectory;
    }

    /**
     * @return {@link #overwrite}
     */
    public boolean isOverwrite()
    {
        return overwrite;
    }

    /**
     * @param overwrite true to overwrite false otherwise.
     */
    public void setOverwrite( boolean overwrite )
    {
        this.overwrite = overwrite;
    }

    /**
     * @return {@link #includeEmptyDirs}
     */
    public boolean isIncludeEmptyDirs()
    {
        return includeEmptyDirs;
    }

    /**
     * @param includeEmptyDirs true/false.
     */
    public void setIncludeEmptyDirs( boolean includeEmptyDirs )
    {
        this.includeEmptyDirs = includeEmptyDirs;
    }

    /**
     * @return {@link #filters}
     */
    public List<String> getFilters()
    {
        return filters;
    }

    /**
     * @param filters The filters to use.
     */
    public void setFilters( List<String> filters )
    {
        this.filters = filters;
    }

    /**
     * @return {@link #delimiters}
     */
    public LinkedHashSet<String> getDelimiters()
    {
        return delimiters;
    }

    /**
     * @param delimiters The delimiters to use.
     */
    public void setDelimiters( LinkedHashSet<String> delimiters )
    {
        this.delimiters = delimiters;
    }

    /**
     * @return {@link #useDefaultDelimiters}
     */
    public boolean isUseDefaultDelimiters()
    {
        return useDefaultDelimiters;
    }

    /**
     * @param useDefaultDelimiters true to use {@code ${*}}
     */
    public void setUseDefaultDelimiters( boolean useDefaultDelimiters )
    {
        this.useDefaultDelimiters = useDefaultDelimiters;
    }

    /**
     * @return {@link #skip}
     */
    public boolean isSkip()
    {
        return skip;
    }

}
