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.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import net.sourceforge.pmd.PMD;

import org.apache.maven.doxia.siterenderer.Renderer;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.AbstractMavenReport;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.PathTool;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.slf4j.bridge.SLF4JBridgeHandler;

/**
 * Base class for the PMD reports.
 *
 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 * @version $Id$
 */
public abstract class AbstractPmdReport
    extends AbstractMavenReport
{
    /**
     * The output directory for the intermediate XML report.
     */
    @Parameter( property = "project.build.directory", required = true )
    protected File targetDirectory;

    /**
     * The output directory for the final HTML report. Note that this parameter is only evaluated if the goal is run
     * directly from the command line or during the default lifecycle. If the goal is run indirectly as part of a site
     * generation, the output directory configured in the Maven Site Plugin is used instead.
     */
    @Parameter( property = "project.reporting.outputDirectory", required = true )
    protected File outputDirectory;

    /**
     * Site rendering component for generating the HTML report.
     */
    @Component
    private Renderer siteRenderer;

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

    /**
     * Set the output format type, in addition to the HTML report. Must be one of: "none", "csv", "xml", "txt" or the
     * full class name of the PMD renderer to use. See the net.sourceforge.pmd.renderers package javadoc for available
     * renderers. XML is required if the pmd:check goal is being used.
     */
    @Parameter( property = "format", defaultValue = "xml" )
    protected String format = "xml";

    /**
     * Link the violation line numbers to the source xref. Links will be created automatically if the jxr plugin is
     * being used.
     */
    @Parameter( property = "linkXRef", defaultValue = "true" )
    private boolean linkXRef;

    /**
     * Location of the Xrefs to link to.
     */
    @Parameter( defaultValue = "${project.reporting.outputDirectory}/xref" )
    private File xrefLocation;

    /**
     * Location of the Test Xrefs to link to.
     */
    @Parameter( defaultValue = "${project.reporting.outputDirectory}/xref-test" )
    private File xrefTestLocation;

    /**
     * A list of files to exclude from checking. Can contain Ant-style wildcards and double wildcards. Note that these
     * exclusion patterns only operate on the path of a source file relative to its source root directory. In other
     * words, files are excluded based on their package and/or class name. If you want to exclude entire source root
     * directories, use the parameter <code>excludeRoots</code> instead.
     *
     * @since 2.2
     */
    @Parameter
    private List<String> excludes;

    /**
     * A list of files to include from checking. Can contain Ant-style wildcards and double wildcards. Defaults to
     * **\/*.java.
     *
     * @since 2.2
     */
    @Parameter
    private List<String> includes;

    /**
     * Specifies the location of the source directories to be used for PMD.
     * Defaults to <code>project.compileSourceRoots</code>.
     * @since 3.7
     */
    @Parameter( defaultValue = "${project.compileSourceRoots}" )
    private List<String> compileSourceRoots;

    /**
     * The directories containing the test-sources to be used for PMD.
     * Defaults to <code>project.testCompileSourceRoots</code>
     * @since 3.7
     */
    @Parameter( defaultValue = "${project.testCompileSourceRoots}" )
    private List<String> testSourceRoots;

    /**
     * The project source directories that should be excluded.
     *
     * @since 2.2
     */
    @Parameter
    private File[] excludeRoots;

    /**
     * Run PMD on the tests.
     *
     * @since 2.2
     */
    @Parameter( defaultValue = "false" )
    protected boolean includeTests;

    /**
     * Whether to build an aggregated report at the root, or build individual reports.
     *
     * @since 2.2
     */
    @Parameter( property = "aggregate", defaultValue = "false" )
    protected boolean aggregate;

    /**
     * The file encoding to use when reading the Java sources.
     *
     * @since 2.3
     */
    @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
    private String sourceEncoding;

    /**
     * The file encoding when writing non-HTML reports.
     *
     * @since 2.5
     */
    @Parameter( property = "outputEncoding", defaultValue = "${project.reporting.outputEncoding}" )
    private String outputEncoding;

    /**
     * The projects in the reactor for aggregation report.
     */
    @Parameter( property = "reactorProjects", readonly = true )
    protected List<MavenProject> reactorProjects;

    /**
     * Whether to include the xml files generated by PMD/CPD in the site.
     *
     * @since 3.0
     */
    @Parameter( defaultValue = "false" )
    protected boolean includeXmlInSite;

    /**
     * Skip the PMD/CPD report generation if there are no violations or duplications found. Defaults to
     * <code>false</code>.
     *
     * <p>Note: the default value was changed from <code>true</code> to <code>false</code> with version 3.13.0.
     *
     * @since 3.1
     */
    @Parameter( defaultValue = "false" )
    protected boolean skipEmptyReport;

    /**
     * File that lists classes and rules to be excluded from failures.
     * For PMD, this is a properties file. For CPD, this
     * is a text file that contains comma-separated lists of classes
     * that are allowed to duplicate.
     *
     * @since 3.7
     */
    @Parameter( property = "pmd.excludeFromFailureFile", defaultValue = "" )
    protected String excludeFromFailureFile;

    /**
     * Redirect PMD log into maven log out.
     * When enabled, the PMD log output is redirected to maven, so that
     * it is visible in the console together with all the other log output.
     * Also, if maven is started with the debug flag (<code>-X</code> or <code>--debug</code>),
     * the PMD logger is also configured for debug.
     *
     * @since 3.9.0
     */
    @Parameter( defaultValue = "true", property = "pmd.showPmdLog" )
    protected boolean showPmdLog = true;

    /**
     * This holds a strong reference in case we configured the logger to
     * redirect to slf4j. See {@link #showPmdLog}. Without a strong reference,
     * the logger might be garbage collected and the redirect to slf4j is gone.
     */
    private Logger julLogger;

    /** The files that are being analyzed. */
    protected Map<File, PmdFileInfo> filesToProcess;

    /**
     * {@inheritDoc}
     */
    @Override
    protected MavenProject getProject()
    {
        return project;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected Renderer getSiteRenderer()
    {
        return siteRenderer;
    }

    protected String constructXRefLocation( boolean test )
    {
        String location = null;
        if ( linkXRef )
        {
            File xrefLoc = test ? xrefTestLocation : xrefLocation;

            String relativePath =
                PathTool.getRelativePath( outputDirectory.getAbsolutePath(), xrefLoc.getAbsolutePath() );
            if ( StringUtils.isEmpty( relativePath ) )
            {
                relativePath = ".";
            }
            relativePath = relativePath + "/" + xrefLoc.getName();
            if ( xrefLoc.exists() )
            {
                // XRef was already generated by manual execution of a lifecycle binding
                location = relativePath;
            }
            else
            {
                // Not yet generated - check if the report is on its way
                List<ReportPlugin> reportPlugins = project.getReportPlugins();
                for ( ReportPlugin plugin : reportPlugins )
                {
                    String artifactId = plugin.getArtifactId();
                    if ( "maven-jxr-plugin".equals( artifactId ) || "jxr-maven-plugin".equals( artifactId ) )
                    {
                        location = relativePath;
                    }
                }
            }

            if ( location == null )
            {
                getLog().warn( "Unable to locate Source XRef to link to - DISABLED" );
            }
        }
        return location;
    }

    /**
     * Convenience method to get the list of files where the PMD tool will be executed
     *
     * @return a List of the files where the PMD tool will be executed
     * @throws IOException If an I/O error occurs during construction of the
     *                     canonical pathnames of the files
     */
    protected Map<File, PmdFileInfo> getFilesToProcess()
        throws IOException
    {
        if ( aggregate && !project.isExecutionRoot() )
        {
            return Collections.emptyMap();
        }

        if ( excludeRoots == null )
        {
            excludeRoots = new File[0];
        }

        Collection<File> excludeRootFiles = new HashSet<>( excludeRoots.length );

        for ( File file : excludeRoots )
        {
            if ( file.isDirectory() )
            {
                excludeRootFiles.add( file );
            }
        }

        List<PmdFileInfo> directories = new ArrayList<>();

        if ( null == compileSourceRoots )
        {
            compileSourceRoots = project.getCompileSourceRoots();
        }
        if ( compileSourceRoots != null )
        {
            for ( String root : compileSourceRoots )
            {
                File sroot = new File( root );
                if ( sroot.exists() )
                {
                    String sourceXref = constructXRefLocation( false );
                    directories.add( new PmdFileInfo( project, sroot, sourceXref ) );
                }
            }
        }

        if ( null == testSourceRoots )
        {
            testSourceRoots = project.getTestCompileSourceRoots();
        }
        if ( includeTests && testSourceRoots != null )
        {
            for ( String root : testSourceRoots )
            {
                File sroot = new File( root );
                if ( sroot.exists() )
                {
                    String testXref = constructXRefLocation( true );
                    directories.add( new PmdFileInfo( project, sroot, testXref ) );
                }
            }
        }
        if ( aggregate )
        {
            for ( MavenProject localProject : reactorProjects )
            {
                List<String> localCompileSourceRoots = localProject.getCompileSourceRoots();
                for ( String root : localCompileSourceRoots )
                {
                    File sroot = new File( root );
                    if ( sroot.exists() )
                    {
                        String sourceXref = constructXRefLocation( false );
                        directories.add( new PmdFileInfo( localProject, sroot, sourceXref ) );
                    }
                }
                if ( includeTests )
                {
                    List<String> localTestCompileSourceRoots = localProject.getTestCompileSourceRoots();
                    for ( String root : localTestCompileSourceRoots )
                    {
                        File sroot = new File( root );
                        if ( sroot.exists() )
                        {
                            String testXref = constructXRefLocation( true );
                            directories.add( new PmdFileInfo( localProject, sroot, testXref ) );
                        }
                    }
                }
            }

        }

        String excluding = getExcludes();
        getLog().debug( "Exclusions: " + excluding );
        String including = getIncludes();
        getLog().debug( "Inclusions: " + including );

        Map<File, PmdFileInfo> files = new TreeMap<>();

        for ( PmdFileInfo finfo : directories )
        {
            getLog().debug( "Searching for files in directory " + finfo.getSourceDirectory().toString() );
            File sourceDirectory = finfo.getSourceDirectory();
            if ( sourceDirectory.isDirectory() && !isDirectoryExcluded( excludeRootFiles, sourceDirectory ) )
            {
                List<File> newfiles = FileUtils.getFiles( sourceDirectory, including, excluding );
                for ( File newfile : newfiles )
                {
                    files.put( newfile.getCanonicalFile(), finfo );
                }
            }
        }

        return files;
    }

    private boolean isDirectoryExcluded( Collection<File> excludeRootFiles, File sourceDirectoryToCheck )
    {
        boolean returnVal = false;
        for ( File excludeDir : excludeRootFiles )
        {
            try
            {
                if ( sourceDirectoryToCheck.getCanonicalPath().startsWith( excludeDir.getCanonicalPath() ) )
                {
                    getLog().debug( "Directory " + sourceDirectoryToCheck.getAbsolutePath()
                                        + " has been excluded as it matches excludeRoot "
                                        + excludeDir.getAbsolutePath() );
                    returnVal = true;
                    break;
                }
            }
            catch ( IOException e )
            {
                getLog().warn( "Error while checking " + sourceDirectoryToCheck
                               + " whether it should be excluded.", e );
            }
        }
        return returnVal;
    }

    /**
     * Gets the comma separated list of effective include patterns.
     *
     * @return The comma separated list of effective include patterns, never <code>null</code>.
     */
    private String getIncludes()
    {
        Collection<String> patterns = new LinkedHashSet<>();
        if ( includes != null )
        {
            patterns.addAll( includes );
        }
        if ( patterns.isEmpty() )
        {
            patterns.add( "**/*.java" );
        }
        return StringUtils.join( patterns.iterator(), "," );
    }

    /**
     * Gets the comma separated list of effective exclude patterns.
     *
     * @return The comma separated list of effective exclude patterns, never <code>null</code>.
     */
    private String getExcludes()
    {
        Collection<String> patterns = new LinkedHashSet<>( FileUtils.getDefaultExcludesAsList() );
        if ( excludes != null )
        {
            patterns.addAll( excludes );
        }
        return StringUtils.join( patterns.iterator(), "," );
    }

    protected boolean isHtml()
    {
        return "html".equals( format );
    }

    protected boolean isXml()
    {
        return "xml".equals( format );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean canGenerateReport()
    {
        if ( aggregate && !project.isExecutionRoot() )
        {
            return false;
        }

        if ( "pom".equals( project.getPackaging() ) && !aggregate )
        {
            return false;
        }

        // if format is XML, we need to output it even if the file list is empty
        // so the "check" goals can check for failures
        if ( isXml() )
        {
            return true;
        }
        try
        {
            filesToProcess = getFilesToProcess();
            if ( filesToProcess.isEmpty() )
            {
                return false;
            }
        }
        catch ( IOException e )
        {
            getLog().error( e );
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected String getOutputDirectory()
    {
        return outputDirectory.getAbsolutePath();
    }

    protected String getSourceEncoding()
    {
        return sourceEncoding;
    }

    /**
     * Gets the effective reporting output files encoding.
     *
     * @return The effective reporting output file encoding, never <code>null</code>.
     * @since 2.5
     */
    protected String getOutputEncoding()
    {
        return ( outputEncoding != null ) ? outputEncoding : ReaderFactory.UTF_8;
    }

    protected void setupPmdLogging()
    {
        if ( !showPmdLog )
        {
            return;
        }

        Logger logger = Logger.getLogger( "net.sourceforge.pmd" );

        boolean slf4jBridgeAlreadyAdded = false;
        for ( Handler handler : logger.getHandlers() )
        {
            if ( handler instanceof SLF4JBridgeHandler )
            {
                slf4jBridgeAlreadyAdded = true;
                break;
            }
        }

        if ( slf4jBridgeAlreadyAdded )
        {
            return;
        }

        SLF4JBridgeHandler handler = new SLF4JBridgeHandler();
        SimpleFormatter formatter = new SimpleFormatter();
        handler.setFormatter( formatter );
        logger.setUseParentHandlers( false );
        logger.addHandler( handler );
        handler.setLevel( Level.ALL );
        logger.setLevel( Level.ALL );
        julLogger = logger;
        julLogger.fine(  "Configured jul-to-slf4j bridge for " + logger.getName() );
    }

    static String getPmdVersion()
    {
        try
        {
            return (String) PMD.class.getField( "VERSION" ).get( null );
        }
        catch ( IllegalAccessException e )
        {
            throw new RuntimeException( "PMD VERSION field not accessible", e );
        }
        catch ( NoSuchFieldException e )
        {
            throw new RuntimeException( "PMD VERSION field not found", e );
        }
    }
}