/*
 * 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.clean;

/*
 * 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.io.IOException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

/**
 * Goal which cleans the build.
 * <p>
 * This attempts to clean a project's working directory of the files that were generated at build-time. By default, it
 * discovers and deletes the directories configured in <code>project.build.directory</code>,
 * <code>project.build.outputDirectory</code>, <code>project.build.testOutputDirectory</code>, and
 * <code>project.reporting.outputDirectory</code>.
 * </p>
 * <p>
 * Files outside the default may also be included in the deletion by configuring the <code>filesets</code> tag.
 * </p>
 *
 * @author <a href="mailto:evenisse@maven.org">Emmanuel Venisse</a>
 * @see org.apache.maven.plugins.clean.Fileset
 * @since 2.0
 */
@Mojo(name = "clean", threadSafe = true)
public class CleanMojo extends AbstractMojo {

    public static final String FAST_MODE_BACKGROUND = "background";

    public static final String FAST_MODE_AT_END = "at-end";

    public static final String FAST_MODE_DEFER = "defer";

    /**
     * This is where build results go.
     */
    @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true)
    private File directory;

    /**
     * This is where compiled classes go.
     */
    @Parameter(defaultValue = "${project.build.outputDirectory}", readonly = true, required = true)
    private File outputDirectory;

    /**
     * This is where compiled test classes go.
     */
    @Parameter(defaultValue = "${project.build.testOutputDirectory}", readonly = true, required = true)
    private File testOutputDirectory;

    /**
     * This is where the site plugin generates its pages.
     *
     * @since 2.1.1
     */
    @Parameter(defaultValue = "${project.build.outputDirectory}", readonly = true, required = true)
    private File reportDirectory;

    /**
     * Sets whether the plugin runs in verbose mode. As of plugin version 2.3, the default value is derived from Maven's
     * global debug flag (compare command line switch <code>-X</code>). <br/>
     * Starting with <b>3.0.0</b> the property has been renamed from <code>clean.verbose</code> to
     * <code>maven.clean.verbose</code>.
     *
     * @since 2.1
     */
    @Parameter(property = "maven.clean.verbose")
    private Boolean verbose;

    /**
     * The list of file sets to delete, in addition to the default directories. For example:
     *
     * <pre>
     * &lt;filesets&gt;
     *   &lt;fileset&gt;
     *     &lt;directory&gt;src/main/generated&lt;/directory&gt;
     *     &lt;followSymlinks&gt;false&lt;/followSymlinks&gt;
     *     &lt;useDefaultExcludes&gt;true&lt;/useDefaultExcludes&gt;
     *     &lt;includes&gt;
     *       &lt;include&gt;*.java&lt;/include&gt;
     *     &lt;/includes&gt;
     *     &lt;excludes&gt;
     *       &lt;exclude&gt;Template*&lt;/exclude&gt;
     *     &lt;/excludes&gt;
     *   &lt;/fileset&gt;
     * &lt;/filesets&gt;
     * </pre>
     *
     * @since 2.1
     */
    @Parameter
    private Fileset[] filesets;

    /**
     * Sets whether the plugin should follow symbolic links while deleting files from the default output directories of
     * the project. Not following symlinks requires more IO operations and heap memory, regardless whether symlinks are
     * actually present. So projects with a huge output directory that knowingly does not contain symlinks can improve
     * performance by setting this parameter to <code>true</code>. <br/>
     * Starting with <code>3.0.0</code> the property has been renamed from <code>clean.followSymLinks</code> to
     * <code>maven.clean.followSymLinks</code>.
     *
     * @since 2.1
     */
    @Parameter(property = "maven.clean.followSymLinks", defaultValue = "false")
    private boolean followSymLinks;

    /**
     * Disables the plugin execution. <br/>
     * Starting with <code>3.0.0</code> the property has been renamed from <code>clean.skip</code> to
     * <code>maven.clean.skip</code>.
     *
     * @since 2.2
     */
    @Parameter(property = "maven.clean.skip", defaultValue = "false")
    private boolean skip;

    /**
     * Indicates whether the build will continue even if there are clean errors.
     *
     * @since 2.2
     */
    @Parameter(property = "maven.clean.failOnError", defaultValue = "true")
    private boolean failOnError;

    /**
     * Indicates whether the plugin should undertake additional attempts (after a short delay) to delete a file if the
     * first attempt failed. This is meant to help deleting files that are temporarily locked by third-party tools like
     * virus scanners or search indexing.
     *
     * @since 2.4.2
     */
    @Parameter(property = "maven.clean.retryOnError", defaultValue = "true")
    private boolean retryOnError;

    /**
     * Disables the deletion of the default output directories configured for a project. If set to <code>true</code>,
     * only the files/directories selected via the parameter {@link #filesets} will be deleted. <br/>
     * Starting with <b>3.0.0</b> the property has been renamed from <code>clean.excludeDefaultDirectories</code> to
     * <code>maven.clean.excludeDefaultDirectories</code>.
     *
     * @since 2.3
     */
    @Parameter(property = "maven.clean.excludeDefaultDirectories", defaultValue = "false")
    private boolean excludeDefaultDirectories;

    /**
     * Enables fast clean if possible. If set to <code>true</code>, when the plugin is executed, a directory to
     * be deleted will be atomically moved inside the <code>maven.clean.fastDir</code> directory and a thread will
     * be launched to delete the needed files in the background.  When the build is completed, maven will wait
     * until all the files have been deleted.  If any problem occurs during the atomic move of the directories,
     * the plugin will default to the traditional deletion mechanism.
     *
     * @since 3.2
     */
    @Parameter(property = "maven.clean.fast", defaultValue = "false")
    private boolean fast;

    /**
     * When fast clean is specified, the <code>fastDir</code> property will be used as the location where directories
     * to be deleted will be moved prior to background deletion.  If not specified, the
     * <code>${maven.multiModuleProjectDirectory}/target/.clean</code> directory will be used.  If the
     * <code>${build.directory}</code> has been modified, you'll have to adjust this property explicitly.
     * In order for fast clean to work correctly, this directory and the various directories that will be deleted
     * should usually reside on the same volume. The exact conditions are system dependant though, but if an atomic
     * move is not supported, the standard deletion mechanism will be used.
     *
     * @since 3.2
     * @see #fast
     */
    @Parameter(property = "maven.clean.fastDir")
    private File fastDir;

    /**
     * Mode to use when using fast clean.  Values are: <code>background</code> to start deletion immediately and
     * waiting for all files to be deleted when the session ends, <code>at-end</code> to indicate that the actual
     * deletion should be performed synchronously when the session ends, or <code>defer</code> to specify that
     * the actual file deletion should be started in the background when the session ends (this should only be used
     * when maven is embedded in a long running process).
     *
     * @since 3.2
     * @see #fast
     */
    @Parameter(property = "maven.clean.fastMode", defaultValue = FAST_MODE_BACKGROUND)
    private String fastMode;

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

    /**
     * Deletes file-sets in the following project build directory order: (source) directory, output directory, test
     * directory, report directory, and then the additional file-sets.
     *
     * @throws MojoExecutionException When a directory failed to get deleted.
     * @see org.apache.maven.plugin.Mojo#execute()
     */
    public void execute() throws MojoExecutionException {
        if (skip) {
            getLog().info("Clean is skipped.");
            return;
        }

        String multiModuleProjectDirectory =
                session != null ? session.getSystemProperties().getProperty("maven.multiModuleProjectDirectory") : null;
        File fastDir;
        if (fast && this.fastDir != null) {
            fastDir = this.fastDir;
        } else if (fast && multiModuleProjectDirectory != null) {
            fastDir = new File(multiModuleProjectDirectory, "target/.clean");
        } else {
            fastDir = null;
            if (fast) {
                getLog().warn("Fast clean requires maven 3.3.1 or newer, "
                        + "or an explicit directory to be specified with the 'fastDir' configuration of "
                        + "this plugin, or the 'maven.clean.fastDir' user property to be set.");
            }
        }
        if (fast
                && !FAST_MODE_BACKGROUND.equals(fastMode)
                && !FAST_MODE_AT_END.equals(fastMode)
                && !FAST_MODE_DEFER.equals(fastMode)) {
            throw new IllegalArgumentException("Illegal value '" + fastMode + "' for fastMode. Allowed values are '"
                    + FAST_MODE_BACKGROUND + "', '" + FAST_MODE_AT_END + "' and '" + FAST_MODE_DEFER + "'.");
        }

        Cleaner cleaner = new Cleaner(session, getLog(), isVerbose(), fastDir, fastMode);

        try {
            for (File directoryItem : getDirectories()) {
                if (directoryItem != null) {
                    cleaner.delete(directoryItem, null, followSymLinks, failOnError, retryOnError);
                }
            }

            if (filesets != null) {
                for (Fileset fileset : filesets) {
                    if (fileset.getDirectory() == null) {
                        throw new MojoExecutionException("Missing base directory for " + fileset);
                    }
                    GlobSelector selector = new GlobSelector(
                            fileset.getIncludes(), fileset.getExcludes(), fileset.isUseDefaultExcludes());
                    cleaner.delete(
                            fileset.getDirectory(), selector, fileset.isFollowSymlinks(), failOnError, retryOnError);
                }
            }
        } catch (IOException e) {
            throw new MojoExecutionException("Failed to clean project: " + e.getMessage(), e);
        }
    }

    /**
     * Indicates whether verbose output is enabled.
     *
     * @return <code>true</code> if verbose output is enabled, <code>false</code> otherwise.
     */
    private boolean isVerbose() {
        return (verbose != null) ? verbose : getLog().isDebugEnabled();
    }

    /**
     * Gets the directories to clean (if any). The returned array may contain null entries.
     *
     * @return The directories to clean or an empty array if none, never <code>null</code>.
     */
    private File[] getDirectories() {
        File[] directories;
        if (excludeDefaultDirectories) {
            directories = new File[0];
        } else {
            directories = new File[] {directory, outputDirectory, testOutputDirectory, reportDirectory};
        }
        return directories;
    }
}
