package org.apache.rat.mp;

/*
 * 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 java.io.InputStream;
import java.io.Writer;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.xml.transform.TransformerConfigurationException;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.rat.Defaults;
import org.apache.rat.Report;
import org.apache.rat.ReportConfiguration;
import org.apache.rat.analysis.IHeaderMatcher;
import org.apache.rat.analysis.util.HeaderMatcherMultiplexer;
import org.apache.rat.api.RatException;
import org.apache.rat.license.ILicenseFamily;
import org.apache.rat.report.IReportable;
import org.apache.rat.report.claim.ClaimStatistic;
import org.codehaus.plexus.util.DirectoryScanner;

/**
 * Abstract base class for Mojos, which are running Rat.
 */
public abstract class AbstractRatMojo extends AbstractMojo {
    /**
     * The Maven specific default excludes.
     */
    static final List<String> MAVEN_DEFAULT_EXCLUDES = Collections
            .unmodifiableList(Arrays.asList("target/**/*", //
                    "cobertura.ser", //
                    "release.properties", //
                    "pom.xml.releaseBackup"));

    /**
     * The Eclipse specific default excludes.
     */
    static final List<String> ECLIPSE_DEFAULT_EXCLUDES = Collections
            .unmodifiableList(Arrays.asList(".classpath",//
                    ".project", //
                    ".settings/**/*"));

    /**
     * The IDEA specific default excludes.
     */
    static final List<String> IDEA_DEFAULT_EXCLUDES = Collections
            .unmodifiableList(Arrays.asList(//
                    "*.iml", //
                    "*.ipr", //
                    "*.iws", //
                    ".idea/**/*"));

    /**
     * The base directory, in which to search for files.
     *
     */
    @Parameter(property = "rat.basedir", defaultValue = "${basedir}", required = true)
    private File basedir;

    /**
     * Specifies the licenses to accept. Deprecated, use {@link #licenses}
     * instead.
     *
     * @deprecated Use {@link #licenses} instead.
     */
    @Deprecated
    @Parameter
    private HeaderMatcherSpecification[] licenseMatchers;

    /**
     * Specifies the licenses to accept. By default, these are added to the
     * default licenses, unless you set {@link #addDefaultLicenseMatchers} to
     * true.
     *
     * @since 0.8
     */
    @Parameter
    private IHeaderMatcher[] licenses;

    /**
     * The set of approved license family names.
     *
     * @deprecated Use {@link #licenseFamilies} instead.
     */
    @Deprecated
    private LicenseFamilySpecification[] licenseFamilyNames;

    /**
     * Specifies the license families to accept.
     *
     * @since 0.8
     */
    @Parameter
    private ILicenseFamily[] licenseFamilies;

    /**
     * Whether to add the default list of license matchers.
     *
     */
    @Parameter(property = "rat.addDefaultLicenseMatchers", defaultValue = "true")
    private boolean addDefaultLicenseMatchers;

    /**
     * Specifies files, which are included in the report. By default, all files
     * are included.
     *
     */
    @Parameter
    private String[] includes;

    /**
     * Specifies files, which are excluded in the report. By default, no files
     * are excluded.
     *
     */
    @Parameter
    private String[] excludes;

    /**
     * Whether to use the default excludes when scanning for files. The default
     * excludes are:
     * <ul>
     * <li>meta data files for version control systems</li>
     * <li>temporary files used by Maven, see <a
     * href="#useMavenDefaultExcludes">useMavenDefaultExcludes</a></li>
     * <li>configuration files for Eclipse, see <a
     * href="#useEclipseDefaultExcludes">useEclipseDefaultExcludes</a></li>
     * <li>configuration files for IDEA, see <a
     * href="#useIdeaDefaultExcludes">useIdeaDefaultExcludes</a></li>
     * </ul>
     */
    @Parameter(property = "rat.useDefaultExcludes", defaultValue = "true")
    private boolean useDefaultExcludes;

    /**
     * Whether to use the Maven specific default excludes when scanning for
     * files. Maven specific default excludes are given by the constant
     * MAVEN_DEFAULT_EXCLUDES: The <code>target</code> directory, the
     * <code>cobertura.ser</code> file, and so on.
     */
    @Parameter(property = "rat.useMavenDefaultExcludes", defaultValue = "true")
    private boolean useMavenDefaultExcludes;

    /**
     * Whether to use the Eclipse specific default excludes when scanning for
     * files. Eclipse specific default excludes are given by the constant
     * ECLIPSE_DEFAULT_EXCLUDES: The <code>.classpath</code> and
     * <code>.project</code> files, the <code>.settings</code> directory, and so
     * on.
     */
    @Parameter(property = "rat.useEclipseDefaultExcludes", defaultValue = "true")
    private boolean useEclipseDefaultExcludes;

    /**
     * Whether to use the IDEA specific default excludes when scanning for
     * files. IDEA specific default excludes are given by the constant
     * IDEA_DEFAULT_EXCLUDES: The <code>*.iml</code>, <code>*.ipr</code> and
     * <code>*.iws</code> files and the <code>.idea</code> directory.
     */
    @Parameter(property = "rat.useIdeaDefaultExcludes", defaultValue = "true")
    private boolean useIdeaDefaultExcludes;

    /**
     * Whether to exclude subprojects. This is recommended, if you want a
     * separate apache-rat-plugin report for each subproject.
     *
     */
    @Parameter(property = "rat.excludeSubprojects", defaultValue = "true")
    private boolean excludeSubProjects;

    /**
    * Holds the maven-internal project to allow resolution of artifact properties during mojo runs.
    */
    @Parameter(defaultValue = "${project}", required = true, readonly = true)
    private MavenProject project;

    /**
     * @return Returns the Maven project.
     */
    protected MavenProject getProject() {
        return project;
    }

    /**
     * Returns the set of {@link IHeaderMatcher header matchers} to use.
     *
     * @throws MojoFailureException
     *             An error in the plugin configuration was detected.
     * @throws MojoExecutionException
     *             An error occurred while calculating the result.
     * @return Array of license matchers to use
     */
    protected IHeaderMatcher[] getLicenseMatchers()
            throws MojoFailureException, MojoExecutionException {
        final List<IHeaderMatcher> list = new ArrayList<IHeaderMatcher>();
        if (licenses != null) {
            list.addAll(Arrays.asList(licenses));
        }

        if (licenseMatchers != null) {
            for (final HeaderMatcherSpecification spec : licenseMatchers) {
                final String className = spec.getClassName();
                final IHeaderMatcher headerMatcher = newInstance(
                        IHeaderMatcher.class, className);
                list.add(headerMatcher);
            }
        }

        if (addDefaultLicenseMatchers) {
            list.addAll(Arrays.asList(Defaults.DEFAULT_MATCHERS));
        }
        return list.toArray(new IHeaderMatcher[list.size()]);
    }

    private <T> T newInstance(final Class<T> clazz, final String className)
            throws MojoExecutionException, MojoFailureException {
        try {
            final ClassLoader cl = Thread.currentThread()
                    .getContextClassLoader();
            @SuppressWarnings("unchecked") // incorrect cast will be caught below
            final T o = (T) cl.loadClass(className).newInstance();

            if (!clazz.isAssignableFrom(o.getClass())) {
                throw new MojoFailureException("The class "
                        + o.getClass().getName() + " does not implement "
                        + clazz.getName());
            }
            return o;
        } catch (InstantiationException e) {
            throw new MojoExecutionException("Failed to instantiate class "
                    + className + ": " + e.getMessage(), e);
        } catch (ClassCastException e) {
            throw new MojoExecutionException("The class " + className
                    + " is not implementing " + clazz.getName() + ": "
                    + e.getMessage(), e);
        } catch (IllegalAccessException e) {
            throw new MojoExecutionException("Illegal access to class "
                    + className + ": " + e.getMessage(), e);
        } catch (ClassNotFoundException e) {
            throw new MojoExecutionException("Class " + className
                    + " not found: " + e.getMessage(), e);
        }
    }

    /**
     * Adds the given string array to the list.
     *
     * @param pList
     *            The list to which the array elements are being added.
     * @param pArray
     *            The strings to add to the list.
     */
    private static void add(List<String> pList, String[] pArray) {
        if (pArray != null) {
            Collections.addAll(pList, pArray);
        }
    }

    /**
     * Creates an iterator over the files to check.
     *
     * @return A container of files, which are being checked.
     */
    protected IReportable getResources() {
        final DirectoryScanner ds = new DirectoryScanner();
        ds.setBasedir(basedir);
        setExcludes(ds);
        setIncludes(ds);
        ds.scan();
        whenDebuggingLogExcludedFiles(ds);
        final String[] files = ds.getIncludedFiles();
        logAboutIncludedFiles(files);
        try {
            return new FilesReportable(basedir, files);
        } catch (IOException e) {
            throw new UndeclaredThrowableException(e);
        }
    }

    private void logAboutIncludedFiles(final String[] files) {
        if (files.length == 0) {
            getLog().warn("No resources included.");
        } else {
            getLog().info(
                    files.length
                            + " resources included (use -debug for more details)");
            if (getLog().isDebugEnabled()) {
                for (String resource : files) {
                    getLog().debug(" - included " + resource);
                }
            }
        }
    }

    private void whenDebuggingLogExcludedFiles(final DirectoryScanner ds) {
        if (getLog().isDebugEnabled()) {
            final String[] excludedFiles = ds.getExcludedFiles();
            if (excludedFiles.length == 0) {
                getLog().debug("No excluded resources.");
            } else {
                getLog().debug(
                        "Excluded " + excludedFiles.length + " resources:");
                for (final String resource : excludedFiles) {
                    getLog().debug(" - excluded " + resource);
                }
            }
        }
    }

    private void setIncludes(DirectoryScanner ds) {
        if (includes != null) {
            ds.setIncludes(includes);
        }
    }

    private void setExcludes(DirectoryScanner ds) {
        final List<String> excludeList = buildDefaultExclusions();
        if (excludes == null || excludes.length == 0) {
            getLog().info("No excludes explicitly specified.");
        } else {
            for (String exclude : excludes) {
                getLog().info("Exclude: " + exclude);
            }
        }
        add(excludeList, excludes);
        if (!excludeList.isEmpty()) {
            String[] allExcludes = excludeList.toArray(new String[excludeList
                    .size()]);
            ds.setExcludes(allExcludes);
        }
    }

    private List<String> buildDefaultExclusions() {
        final List<String> results = new ArrayList<String>();

        addPlexusDefaults(results);

        addMavenDefaults(results);

        addEclipseDefaults(results);

        addIdeaDefaults(results);

        if (excludeSubProjects && project != null
                && project.getModules() != null) {
            for (Object o : project.getModules()) {
                String moduleSubPath = (String) o;
                results.add(moduleSubPath + "/**/*");
            }
        }

        getLog().debug("Finished creating list of implicit excludes.");
        if (results.isEmpty()) {
            getLog().info("No excludes implicitly specified.");
        } else {
            getLog().info(
                    results.size()
                            + " implicit excludes (use -debug for more details).");
            for (final String exclude : results) {
                getLog().debug("Implicit exclude: " + exclude);
            }
        }

        return results;
    }

    private void addPlexusDefaults(final List<String> excludeList1) {
        if (useDefaultExcludes) {
            getLog().debug("Adding plexus default exclusions...");
            Collections.addAll(excludeList1, DirectoryScanner.DEFAULTEXCLUDES);
        } else {
            getLog().debug(
                    "rat.useDefaultExcludes set to false. "
                            + "Plexus default exclusions will not be added");
        }
    }

    private void addMavenDefaults(final List<String> excludeList1) {
        if (useMavenDefaultExcludes) {
            getLog().debug(
                    "Adding exclusions often needed by Maven projects...");
            excludeList1.addAll(MAVEN_DEFAULT_EXCLUDES);
        } else {
            getLog().debug(
                    "rat.useMavenDefaultExcludes set to false. "
                            + "Exclusions often needed by Maven projects will not be added.");
        }
    }

    private void addEclipseDefaults(final List<String> excludeList1) {
        if (useEclipseDefaultExcludes) {
            getLog().debug(
                    "Adding exclusions often needed by projects "
                            + "developed in Eclipse...");
            excludeList1.addAll(ECLIPSE_DEFAULT_EXCLUDES);
        } else {
            getLog().debug(
                    "rat.useEclipseDefaultExcludes set to false. "
                            + "Exclusions often needed by projects developed in "
                            + "Eclipse will not be added.");
        }
    }

    private void addIdeaDefaults(final List<String> excludeList1) {
        if (useIdeaDefaultExcludes) {
            getLog().debug(
                    "Adding exclusions often needed by projects "
                            + "developed in IDEA...");
            excludeList1.addAll(IDEA_DEFAULT_EXCLUDES);
        } else {
            getLog().debug(
                    "rat.useIdeaDefaultExcludes set to false. "
                            + "Exclusions often needed by projects developed in "
                            + "IDEA will not be added.");
        }
    }

    /**
     * Writes the report to the given stream.
     *
     * @param out
     *            The target writer, to which the report is being written.
     * @param style
     *            The stylesheet to use, or <code>null</code> for raw XML
     *
     * @return the current statistic.
     *
     * @throws MojoFailureException
     *             An error in the plugin configuration was detected.
     * @throws MojoExecutionException
     *             Another error occurred while creating the report.
     */
    protected ClaimStatistic createReport(Writer out, InputStream style)
            throws MojoExecutionException, MojoFailureException {
        final ReportConfiguration configuration = getConfiguration();
        try {
            if (style != null) {
                return Report.report(out, getResources(), style, configuration);
            } else {
                return Report.report(getResources(), out, configuration);
            }
        } catch (TransformerConfigurationException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        } catch (IOException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        } catch (InterruptedException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        } catch (RatException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        }
    }

    protected ReportConfiguration getConfiguration()
            throws MojoFailureException, MojoExecutionException {
        final ReportConfiguration configuration = new ReportConfiguration();
        configuration.setHeaderMatcher(new HeaderMatcherMultiplexer(
                getLicenseMatchers()));
        configuration.setApprovedLicenseNames(getApprovedLicenseNames());
        return configuration;
    }

    private ILicenseFamily[] getApprovedLicenseNames()
            throws MojoExecutionException, MojoFailureException {
        final List<ILicenseFamily> list = new ArrayList<ILicenseFamily>();
        if (licenseFamilies != null) {
            list.addAll(Arrays.asList(licenseFamilies));
        }
        if (licenseFamilyNames != null) {
            for (LicenseFamilySpecification spec : licenseFamilyNames) {
                list.add(newInstance(ILicenseFamily.class, spec.getClassName()));
            }
        }

        if (list.isEmpty()) {
            return null;
        }
        return list.toArray(new ILicenseFamily[list.size()]);
    }
}
