package org.apache.maven.plugins.pmd;

/*
 * 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.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.plugins.pmd.exec.PmdExecutor;
import org.apache.maven.plugins.pmd.exec.PmdRequest;
import org.apache.maven.plugins.pmd.exec.PmdResult;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.shared.artifact.filter.resolve.AndFilter;
import org.apache.maven.shared.artifact.filter.resolve.ExclusionsFilter;
import org.apache.maven.shared.artifact.filter.resolve.ScopeFilter;
import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
import org.apache.maven.shared.utils.logging.MessageUtils;
import org.apache.maven.toolchain.Toolchain;
import org.codehaus.plexus.resource.ResourceManager;
import org.codehaus.plexus.resource.loader.FileResourceCreationException;
import org.codehaus.plexus.resource.loader.FileResourceLoader;
import org.codehaus.plexus.resource.loader.ResourceNotFoundException;
import org.codehaus.plexus.util.StringUtils;

import net.sourceforge.pmd.renderers.Renderer;

/**
 * Creates a PMD site report based on the rulesets and configuration set in the plugin.
 * It can also generate a pmd output file aside from the site report in any of the following formats: xml, csv or txt.
 *
 * @author Brett Porter
 * @version $Id$
 * @since 2.0
 */
@Mojo( name = "pmd", threadSafe = true, requiresDependencyResolution = ResolutionScope.TEST )
public class PmdReport
    extends AbstractPmdReport
{
    /**
     * The target JDK to analyze based on. Should match the source used in the compiler plugin. Valid values
     * with the default PMD version are
     * currently <code>1.3</code>, <code>1.4</code>, <code>1.5</code>, <code>1.6</code>, <code>1.7</code>,
     * <code>1.8</code>, <code>9</code>, <code>10</code>, <code>11</code>, <code>12</code>, <code>13</code>,
     * <code>14</code>, <code>15</code>, <code>16</code>, <code>17</code>, <code>18</code>, and <code>19</code>.
     *
     * <p> You can override the default PMD version by specifying PMD as a dependency,
     * see <a href="examples/upgrading-PMD-at-runtime.html">Upgrading PMD at Runtime</a>.</p>
     *
     * <p>
     *   <b>Note:</b> this parameter is only used if the language parameter is set to <code>java</code>.
     * </p>
     */
    @Parameter( property = "targetJdk", defaultValue = "${maven.compiler.source}" )
    private String targetJdk;

    /**
     * The programming language to be analyzed by PMD. Valid values are currently <code>java</code>,
     * <code>javascript</code> and <code>jsp</code>.
     *
     * @since 3.0
     */
    @Parameter( defaultValue = "java" )
    private String language;

    /**
     * The rule priority threshold; rules with lower priority than this will not be evaluated.
     *
     * @since 2.1
     */
    @Parameter( property = "minimumPriority", defaultValue = "5" )
    private int minimumPriority = 5;

    /**
     * Skip the PMD report generation. Most useful on the command line via "-Dpmd.skip=true".
     *
     * @since 2.1
     */
    @Parameter( property = "pmd.skip", defaultValue = "false" )
    private boolean skip;

    /**
     * The PMD rulesets to use. See the
     * <a href="https://pmd.github.io/latest/pmd_rules_java.html">Stock Java Rulesets</a> for a
     * list of available rules.
     * Defaults to a custom ruleset provided by this maven plugin
     * (<code>/rulesets/java/maven-pmd-plugin-default.xml</code>).
     */
    @Parameter
    String[] rulesets = new String[] { "/rulesets/java/maven-pmd-plugin-default.xml" };

    /**
     * Controls whether the project's compile/test classpath should be passed to PMD to enable its type resolution
     * feature.
     *
     * @since 3.0
     */
    @Parameter( property = "pmd.typeResolution", defaultValue = "true" )
    private boolean typeResolution;

    /**
     * Controls whether PMD will track benchmark information.
     *
     * @since 3.1
     */
    @Parameter( property = "pmd.benchmark", defaultValue = "false" )
    private boolean benchmark;

    /**
     * Benchmark output filename.
     *
     * @since 3.1
     */
    @Parameter( property = "pmd.benchmarkOutputFilename",
                    defaultValue = "${project.build.directory}/pmd-benchmark.txt" )
    private String benchmarkOutputFilename;

    /**
     * Source level marker used to indicate whether a RuleViolation should be suppressed. If it is not set, PMD's
     * default will be used, which is <code>NOPMD</code>. See also <a
     * href="https://pmd.github.io/latest/pmd_userdocs_suppressing_warnings.html">PMD &#x2013; Suppressing warnings</a>.
     *
     * @since 3.4
     */
    @Parameter( property = "pmd.suppressMarker" )
    private String suppressMarker;

    /**
     * per default pmd executions error are ignored to not break the whole
     *
     * @since 3.1
     */
    @Parameter( property = "pmd.skipPmdError", defaultValue = "true" )
    private boolean skipPmdError;

    /**
     * Enables the analysis cache, which speeds up PMD. This
     * requires a cache file, that contains the results of the last
     * PMD run. Thus the cache is only effective, if this file is
     * not cleaned between runs.
     *
     * @since 3.8
     */
    @Parameter( property = "pmd.analysisCache", defaultValue = "false" )
    private boolean analysisCache;

    /**
     * The location of the analysis cache, if it is enabled.
     * This file contains the results of the last PMD run and must not be cleaned
     * between consecutive PMD runs. Otherwise the cache is not in use.
     * If the file doesn't exist, PMD executes as if there is no cache enabled and
     * all files are analyzed. Otherwise only changed files will be analyzed again.
     *
     * @since 3.8
     */
    @Parameter( property = "pmd.analysisCacheLocation", defaultValue = "${project.build.directory}/pmd/pmd.cache" )
    private String analysisCacheLocation;

    /**
     * Also render processing errors into the HTML report.
     * Processing errors are problems, that PMD encountered while executing the rules.
     * It can be parsing errors or exceptions during rule execution.
     * Processing errors indicate a bug in PMD and the information provided help in
     * reporting and fixing bugs in PMD.
     *
     * @since 3.9.0
     */
    @Parameter( property = "pmd.renderProcessingErrors", defaultValue = "true" )
    private boolean renderProcessingErrors = true;

    /**
     * Also render the rule priority into the HTML report.
     *
     * @since 3.10.0
     */
    @Parameter( property = "pmd.renderRuleViolationPriority", defaultValue = "true" )
    private boolean renderRuleViolationPriority = true;

    /**
     * Add a section in the HTML report, that groups the found violations by rule priority
     * in addition to grouping by file.
     *
     * @since 3.12.0
     */
    @Parameter( property = "pmd.renderViolationsByPriority", defaultValue = "true" )
    private boolean renderViolationsByPriority = true;

    /**
     * Add a section in the HTML report that lists the suppressed violations.
     *
     * @since 3.17.0
     */
    @Parameter( property = "pmd.renderSuppressedViolations", defaultValue = "true" )
    private boolean renderSuppressedViolations = true;

    /**
     * Before PMD is executed, the configured rulesets are resolved and copied into this directory.
     * <p>Note: Before 3.13.0, this was by default ${project.build.directory}.
     *
     * @since 3.13.0
     */
    @Parameter( property = "pmd.rulesetsTargetDirectory", defaultValue = "${project.build.directory}/pmd/rulesets" )
    private File rulesetsTargetDirectory;

    /**
     * Used to locate configured rulesets. The rulesets could be on the plugin
     * classpath or in the local project file system.
     */
    @Component
    private ResourceManager locator;

    @Component
    private DependencyResolver dependencyResolver;

    /**
     * Contains the result of the last PMD execution.
     * It might be <code>null</code> which means, that PMD
     * has not been executed yet.
     */
    private PmdResult pmdResult;

    /**
     * {@inheritDoc}
     */
    @Override
    public String getName( Locale locale )
    {
        return getBundle( locale ).getString( "report.pmd.name" );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getDescription( Locale locale )
    {
        return getBundle( locale ).getString( "report.pmd.description" );
    }

    /**
     * Configures the PMD rulesets to be used directly.
     * Note: Usually the rulesets are configured via the property.
     *
     * @param rulesets the PMD rulesets to be used.
     * @see #rulesets
     */
    public void setRulesets( String[] rulesets )
    {
        this.rulesets = Arrays.copyOf( rulesets, rulesets.length );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void executeReport( Locale locale )
        throws MavenReportException
    {
        ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
        try
        {
            Thread.currentThread().setContextClassLoader( this.getClass().getClassLoader() );

            generateMavenSiteReport( locale );
        }
        finally
        {
            Thread.currentThread().setContextClassLoader( origLoader );
        }
    }

    @Override
    public boolean canGenerateReport()
    {
        if ( skip )
        {
            getLog().info( "Skipping PMD execution" );
            return false;
        }

        boolean result = super.canGenerateReport();
        if ( result )
        {
            try
            {
                executePmd();
                if ( skipEmptyReport )
                {
                    result = pmdResult.hasViolations();
                    if ( !result )
                    {
                        getLog().debug( "Skipping report since skipEmptyReport is true and "
                                            + "there are no PMD violations." );
                    }
                }
            }
            catch ( MavenReportException e )
            {
                throw new RuntimeException( e );
            }
        }
        return result;
    }

    private void executePmd()
        throws MavenReportException
    {
        if ( pmdResult != null )
        {
            // PMD has already been run
            getLog().debug( "PMD has already been run - skipping redundant execution." );
            return;
        }

        try
        {
            filesToProcess = getFilesToProcess();

            if ( filesToProcess.isEmpty() && !"java".equals( language ) )
            {
                getLog().warn( "No files found to process. Did you add your additional source folders like javascript?"
                                   + " (see also build-helper-maven-plugin)" );
            }
        }
        catch ( IOException e )
        {
            throw new MavenReportException( "Can't get file list", e );
        }


        PmdRequest request = new PmdRequest();
        request.setLanguageAndVersion( language, targetJdk );
        request.setRulesets( resolveRulesets() );
        request.setAuxClasspath( typeResolution ? determineAuxClasspath() : null );
        request.setSourceEncoding( getInputEncoding() );
        request.addFiles( filesToProcess.keySet() );
        request.setMinimumPriority( minimumPriority );
        request.setSuppressMarker( suppressMarker );
        request.setBenchmarkOutputLocation( benchmark ? benchmarkOutputFilename : null );
        request.setAnalysisCacheLocation( analysisCache ? analysisCacheLocation : null );
        request.setExcludeFromFailureFile( excludeFromFailureFile );

        request.setTargetDirectory( targetDirectory.getAbsolutePath() );
        request.setOutputEncoding( getOutputEncoding() );
        request.setFormat( format );
        request.setShowPmdLog( showPmdLog );
        request.setColorizedLog( MessageUtils.isColorEnabled() );
        request.setSkipPmdError( skipPmdError );
        request.setIncludeXmlInSite( includeXmlInSite );
        request.setReportOutputDirectory( getReportOutputDirectory().getAbsolutePath() );
        request.setLogLevel( determineCurrentRootLogLevel() );

        Toolchain tc = getToolchain();
        if ( tc != null )
        {
            getLog().info( "Toolchain in maven-pmd-plugin: " + tc );
            String javaExecutable = tc.findTool( "java" ); //NOI18N
            request.setJavaExecutable( javaExecutable );
        }

        getLog().info( "PMD version: " + AbstractPmdReport.getPmdVersion() );
        pmdResult = PmdExecutor.execute( request );
    }

    /**
     * Resolves the configured rulesets and copies them as files into the {@link #rulesetsTargetDirectory}.
     *
     * @return comma separated list of absolute file paths of ruleset files
     * @throws MavenReportException if a ruleset could not be found
     */
    private List<String> resolveRulesets() throws MavenReportException
    {
        // configure ResourceManager - will search for urls (URLResourceLoader) and files in various directories:
        // in the directory of the current project's pom file - note: extensions might replace the pom file on the fly
        locator.addSearchPath( FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath() );
        // in the current project's directory
        locator.addSearchPath( FileResourceLoader.ID, project.getBasedir().getAbsolutePath() );
        // in the base directory - that's the directory of the initial pom requested to build,
        // e.g. the root of a multi module build
        locator.addSearchPath( FileResourceLoader.ID, session.getRequest().getBaseDirectory() );
        locator.setOutputDirectory( rulesetsTargetDirectory );

        String[] sets = new String[rulesets.length];
        try
        {
            for ( int idx = 0; idx < rulesets.length; idx++ )
            {
                String set = rulesets[idx];
                getLog().debug( "Preparing ruleset: " + set );
                String rulesetFilename = determineRulesetFilename( set );
                File ruleset = locator.getResourceAsFile( rulesetFilename, getLocationTemp( set ) );
                if ( null == ruleset )
                {
                    throw new MavenReportException( "Could not resolve " + set );
                }
                sets[idx] = ruleset.getAbsolutePath();
            }
        }
        catch ( ResourceNotFoundException | FileResourceCreationException e )
        {
            throw new MavenReportException( e.getMessage(), e );
        }
        return Arrays.asList( sets );
    }

    private String determineRulesetFilename( String ruleset )
    {
        String result = ruleset.trim();
        String lowercase = result.toLowerCase( Locale.ROOT );
        if ( lowercase.startsWith( "http://" ) || lowercase.startsWith( "https://" ) || lowercase.endsWith( ".xml" ) )
        {
            return result;
        }

        // assume last part is a single rule, e.g. myruleset.xml/SingleRule
        if ( result.indexOf( '/' ) > -1 )
        {
            String rulesetFilename = result.substring( 0, result.lastIndexOf( '/' ) );
            if ( rulesetFilename.toLowerCase( Locale.ROOT ).endsWith( ".xml" ) )
            {
                return rulesetFilename;
            }
        }
        // maybe a built-in ruleset name, e.g. java-design -> rulesets/java/design.xml
        int dashIndex = lowercase.indexOf( '-' );
        if ( dashIndex > -1 && lowercase.indexOf( '-', dashIndex + 1 ) == -1 )
        {
            String language = result.substring( 0, dashIndex );
            String rulesetName = result.substring( dashIndex + 1 );
            return "rulesets/" + language + "/" + rulesetName + ".xml";
        }
        // fallback - no change of the given ruleset specifier
        return result;
    }

    private void generateMavenSiteReport( Locale locale )
        throws MavenReportException
    {
        Sink sink = getSink();
        PmdReportGenerator doxiaRenderer = new PmdReportGenerator( getLog(), sink, getBundle( locale ),
                isAggregator() );
        doxiaRenderer.setRenderRuleViolationPriority( renderRuleViolationPriority );
        doxiaRenderer.setRenderViolationsByPriority( renderViolationsByPriority );
        doxiaRenderer.setFiles( filesToProcess );
        doxiaRenderer.setViolations( pmdResult.getViolations() );
        if ( renderSuppressedViolations )
        {
            doxiaRenderer.setSuppressedViolations( pmdResult.getSuppressedViolations() );
        }
        if ( renderProcessingErrors )
        {
            doxiaRenderer.setProcessingErrors( pmdResult.getErrors() );
        }

        try
        {
            doxiaRenderer.beginDocument();
            doxiaRenderer.render();
            doxiaRenderer.endDocument();
        }
        catch ( IOException e )
        {
            getLog().warn( "Failure creating the report: " + e.getLocalizedMessage(), e );
        }
    }

    /**
     * Convenience method to get the location of the specified file name.
     *
     * @param name the name of the file whose location is to be resolved
     * @return a String that contains the absolute file name of the file
     */
    protected String getLocationTemp( String name )
    {
        String loc = name;
        if ( loc.indexOf( '/' ) != -1 )
        {
            loc = loc.substring( loc.lastIndexOf( '/' ) + 1 );
        }
        if ( loc.indexOf( '\\' ) != -1 )
        {
            loc = loc.substring( loc.lastIndexOf( '\\' ) + 1 );
        }

        // MPMD-127 in the case that the rules are defined externally on a url
        // we need to replace some special url characters that cannot be
        // used in filenames on disk or produce ackward filenames.
        // replace all occurrences of the following characters: ? : & = %
        loc = loc.replaceAll( "[\\?\\:\\&\\=\\%]", "_" );

        if ( !loc.endsWith( ".xml" ) )
        {
            loc = loc + ".xml";
        }

        getLog().debug( "Before: " + name + " After: " + loc );
        return loc;
    }

    private String determineAuxClasspath() throws MavenReportException
    {
        try
        {
            List<String> classpath = new ArrayList<>();
            if ( isAggregator() )
            {
                List<String> dependencies = new ArrayList<>();

                // collect exclusions for projects within the reactor
                // if module a depends on module b and both are in the reactor
                // then we don't want to resolve the dependency as an artifact.
                List<String> exclusionPatterns = new ArrayList<>();
                for ( MavenProject localProject : getAggregatedProjects() )
                {
                    exclusionPatterns.add( localProject.getGroupId() + ":" + localProject.getArtifactId() );
                }
                TransformableFilter filter = new AndFilter( Arrays.asList(
                        new ExclusionsFilter( exclusionPatterns ),
                        includeTests ? ScopeFilter.including( "compile", "provided", "test" )
                                     : ScopeFilter.including( "compile", "provided" )
                ) );

                for ( MavenProject localProject : getAggregatedProjects() )
                {
                    ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(
                            session.getProjectBuildingRequest() );

                    Iterable<ArtifactResult> resolvedDependencies = dependencyResolver.resolveDependencies(
                            buildingRequest, localProject.getDependencies(), null, filter );

                    for ( ArtifactResult resolvedArtifact : resolvedDependencies )
                    {
                        dependencies.add( resolvedArtifact.getArtifact().getFile().toString() );
                    }

                    List<String> projectClasspath = includeTests ? localProject.getTestClasspathElements()
                            : localProject.getCompileClasspathElements();

                    // Add the project's target folder first
                    classpath.addAll( projectClasspath );
                    if ( !localProject.isExecutionRoot() )
                    {
                        for ( String path : projectClasspath )
                        {
                            File pathFile = new File( path );
                            String[] children = pathFile.list();

                            if ( !pathFile.exists() || ( children != null && children.length == 0 ) )
                            {
                                getLog().warn( "The project " + localProject.getArtifactId()
                                    + " does not seem to be compiled. PMD results might be inaccurate." );
                            }
                        }
                    }

                }

                // Add the dependencies as last entries
                classpath.addAll( dependencies );

                getLog().debug( "Using aggregated aux classpath: " + classpath );
            }
            else
            {
                classpath.addAll( includeTests ? project.getTestClasspathElements()
                                               : project.getCompileClasspathElements() );

                getLog().debug( "Using aux classpath: " + classpath );
            }
            String path = StringUtils.join( classpath.iterator(), File.pathSeparator );
            return path;
        }
        catch ( Exception e )
        {
            throw new MavenReportException( e.getMessage(), e );
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getOutputName()
    {
        return "pmd";
    }

    private static ResourceBundle getBundle( Locale locale )
    {
        return ResourceBundle.getBundle( "pmd-report", locale, PmdReport.class.getClassLoader() );
    }

    /**
     * Create and return the correct renderer for the output type.
     *
     * @return the renderer based on the configured output
     * @throws org.apache.maven.reporting.MavenReportException if no renderer found for the output type
     * @deprecated Use {@link PmdExecutor#createRenderer(String, String)} instead.
     */
    @Deprecated
    public final Renderer createRenderer() throws MavenReportException
    {
        return PmdExecutor.createRenderer( format, getOutputEncoding() );
    }
}
