/*
 * 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.
 */
package org.apache.maven.plugins.resources;

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, readonly = 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;/.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;
    }
}
