package org.apache.maven.plugins.pmd.exec;

/*
 * 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.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.pmd.ExcludeViolationsFromFile;
import org.apache.maven.reporting.MavenReportException;
import org.codehaus.plexus.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.sourceforge.pmd.PmdAnalysis;
import net.sourceforge.pmd.PMDConfiguration;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RulePriority;
import net.sourceforge.pmd.RuleSetLoadException;
import net.sourceforge.pmd.RuleSetLoader;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.benchmark.TextTimingReportRenderer;
import net.sourceforge.pmd.benchmark.TimeTracker;
import net.sourceforge.pmd.benchmark.TimingReport;
import net.sourceforge.pmd.benchmark.TimingReportRenderer;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.renderers.CSVRenderer;
import net.sourceforge.pmd.renderers.HTMLRenderer;
import net.sourceforge.pmd.renderers.Renderer;
import net.sourceforge.pmd.renderers.TextRenderer;
import net.sourceforge.pmd.renderers.XMLRenderer;
import net.sourceforge.pmd.util.Predicate;

/**
 * Executes PMD with the configuration provided via {@link PmdRequest}.
 */
public class PmdExecutor extends Executor
{
    private static final Logger LOG = LoggerFactory.getLogger( PmdExecutor.class );

    public static PmdResult execute( PmdRequest request ) throws MavenReportException
    {
        if ( request.getJavaExecutable() != null )
        {
            return fork( request );
        }

        // make sure the class loaders are correct and call this in the same JVM
        ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
        try
        {
            Thread.currentThread().setContextClassLoader( PmdExecutor.class.getClassLoader() );
            PmdExecutor executor = new PmdExecutor( request );
            return executor.run();
        }
        finally
        {
            Thread.currentThread().setContextClassLoader( origLoader );
        }
    }

    private static PmdResult fork( PmdRequest request )
            throws MavenReportException
    {
        File basePmdDir = new File ( request.getTargetDirectory(), "pmd" );
        basePmdDir.mkdirs();
        File pmdRequestFile = new File( basePmdDir, "pmdrequest.bin" );
        try ( ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream( pmdRequestFile ) ) )
        {
            out.writeObject( request );
        }
        catch ( IOException e )
        {
            throw new MavenReportException( e.getMessage(), e );
        }

        String classpath = buildClasspath();
        ProcessBuilder pb = new ProcessBuilder();
        // note: using env variable instead of -cp cli arg to avoid length limitations under Windows
        pb.environment().put( "CLASSPATH", classpath );
        pb.command().add( request.getJavaExecutable() );
        pb.command().add( PmdExecutor.class.getName() );
        pb.command().add( pmdRequestFile.getAbsolutePath() );

        LOG.debug( "Executing: CLASSPATH={}, command={}", classpath, pb.command() );
        try
        {
            final Process p = pb.start();
            // Note: can't use pb.inheritIO(), since System.out/System.err has been modified after process start
            // and inheritIO would only inherit file handles, not the changed streams.
            ProcessStreamHandler.start( p.getInputStream(), System.out );
            ProcessStreamHandler.start( p.getErrorStream(), System.err );
            int exit = p.waitFor();
            LOG.debug( "PmdExecutor exit code: {}", exit );
            if ( exit != 0 )
            {
                throw new MavenReportException( "PmdExecutor exited with exit code " + exit );
            }
            return new PmdResult( new File( request.getTargetDirectory(), "pmd.xml" ), request.getOutputEncoding() );
        }
        catch ( IOException e )
        {
            throw new MavenReportException( e.getMessage(), e );
        }
        catch ( InterruptedException e )
        {
            Thread.currentThread().interrupt();
            throw new MavenReportException( e.getMessage(), e );
        }
    }

    /**
     * Execute PMD analysis from CLI.
     *
     * <p>
     * Single arg with the filename to the serialized {@link PmdRequest}.
     *
     * <p>
     * Exit-code: 0 = success, 1 = failure in executing
     *
     * @param args
     */
    public static void main( String[] args )
    {
        File requestFile = new File( args[0] );
        try ( ObjectInputStream in = new ObjectInputStream( new FileInputStream( requestFile ) ) )
        {
            PmdRequest request = (PmdRequest) in.readObject();
            PmdExecutor pmdExecutor = new PmdExecutor( request );
            pmdExecutor.setupLogLevel( request.getLogLevel() );
            pmdExecutor.run();
            System.exit( 0 );
        }
        catch ( IOException | ClassNotFoundException | MavenReportException e )
        {
            LOG.error( e.getMessage(), e );
        }
        System.exit( 1 );
    }

    private final PmdRequest request;

    public PmdExecutor( PmdRequest request )
    {
        this.request = Objects.requireNonNull( request );
    }

    private PmdResult run() throws MavenReportException
    {
        setupPmdLogging( request.isShowPmdLog(), request.getLogLevel() );

        PMDConfiguration configuration = new PMDConfiguration();
        LanguageVersion languageVersion = null;
        Language language = LanguageRegistry
                .findLanguageByTerseName( request.getLanguage() != null ? request.getLanguage() : "java" );
        if ( language == null )
        {
            throw new MavenReportException( "Unsupported language: " + request.getLanguage() );
        }
        if ( request.getLanguageVersion() != null )
        {
            languageVersion = language.getVersion( request.getLanguageVersion() );
            if ( languageVersion == null )
            {
                throw new MavenReportException( "Unsupported targetJdk value '" + request.getLanguageVersion() + "'." );
            }
        }
        else
        {
            languageVersion = language.getDefaultVersion();
        }
        LOG.debug( "Using language " + languageVersion );
        configuration.setDefaultLanguageVersion( languageVersion );

        if ( request.getSourceEncoding() != null )
        {
            configuration.setSourceEncoding( request.getSourceEncoding() );
        }

        configuration.prependAuxClasspath( request.getAuxClasspath() );

        if ( request.getSuppressMarker() != null )
        {
            configuration.setSuppressMarker( request.getSuppressMarker() );
        }
        if ( request.getAnalysisCacheLocation() != null )
        {
            configuration.setAnalysisCacheLocation( request.getAnalysisCacheLocation() );
            LOG.debug( "Using analysis cache location: " + request.getAnalysisCacheLocation() );
        }
        else
        {
            configuration.setIgnoreIncrementalAnalysis( true );
        }

        configuration.setRuleSets( request.getRulesets() );
        configuration.setMinimumPriority( RulePriority.valueOf( request.getMinimumPriority() ) );
        if ( request.getBenchmarkOutputLocation() != null )
        {
            configuration.setBenchmark( true );
        }
        List<File> files = request.getFiles();

        Report report = null;

        if ( request.getRulesets().isEmpty() )
        {
            LOG.debug( "Skipping PMD execution as no rulesets are defined." );
        }
        else
        {
            if ( request.getBenchmarkOutputLocation() != null )
            {
                TimeTracker.startGlobalTracking();
            }

            try
            {
                report = processFilesWithPMD( configuration, files );
            }
            finally
            {
                if ( request.getAuxClasspath() != null )
                {
                    ClassLoader classLoader = configuration.getClassLoader();
                    if ( classLoader instanceof Closeable )
                    {
                        Closeable closeable = (Closeable) classLoader;
                        try
                        {
                            closeable.close();
                        }
                        catch ( IOException ex )
                        {
                            // ignore
                        }
                    }
                }
                if ( request.getBenchmarkOutputLocation() != null )
                {
                    TimingReport timingReport = TimeTracker.stopGlobalTracking();
                    writeBenchmarkReport( timingReport, request.getBenchmarkOutputLocation(),
                            request.getOutputEncoding() );
                }
            }
        }

        if ( report != null && !report.getProcessingErrors().isEmpty() )
        {
            List<Report.ProcessingError> errors = report.getProcessingErrors();
            if ( !request.isSkipPmdError() )
            {
                LOG.error( "PMD processing errors:" );
                LOG.error( getErrorsAsString( errors, request.isDebugEnabled() ) );
                throw new MavenReportException( "Found " + errors.size()
                        + " PMD processing errors" );
            }
            LOG.warn( "There are {} PMD processing errors:", errors.size() );
            LOG.warn( getErrorsAsString( errors, request.isDebugEnabled() ) );
        }

        report = removeExcludedViolations( report );
        // always write XML report, as this might be needed by the check mojo
        // we need to output it even if the file list is empty or we have no violations
        // so the "check" goals can check for violations
        writeXmlReport( report );

        // write any other format except for xml and html. xml has just been produced.
        // html format is produced by the maven site formatter. Excluding html here
        // avoids using PMD's own html formatter, which doesn't fit into the maven site
        // considering the html/css styling
        String format = request.getFormat();
        if ( !"html".equals( format ) && !"xml".equals( format ) )
        {
            writeFormattedReport( report );
        }

        return new PmdResult( new File( request.getTargetDirectory(), "pmd.xml" ), request.getOutputEncoding() );
    }

    /**
     * Gets the errors as a single string. Each error is in its own line.
     * @param withDetails if <code>true</code> then add the error details additionally (contains e.g. the stacktrace)
     * @return the errors as string
     */
    private String getErrorsAsString( List<Report.ProcessingError> errors, boolean withDetails )
    {
        List<String> errorsAsString = new ArrayList<>( errors.size() );
        for ( Report.ProcessingError error : errors )
        {
            errorsAsString.add( error.getFile() + ": " + error.getMsg() );
            if ( withDetails )
            {
                errorsAsString.add( error.getDetail() );
            }
        }
        return String.join( System.lineSeparator(), errorsAsString );
    }

    private void writeBenchmarkReport( TimingReport timingReport, String benchmarkOutputLocation, String encoding )
    {
        try ( Writer writer = new OutputStreamWriter( new FileOutputStream( benchmarkOutputLocation ), encoding ) )
        {
            final TimingReportRenderer renderer = new TextTimingReportRenderer();
            renderer.render( timingReport, writer );
        }
        catch ( IOException e )
        {
            LOG.error( "Unable to generate benchmark file: {}", benchmarkOutputLocation, e );
        }
    }

    private Report processFilesWithPMD( PMDConfiguration pmdConfiguration, List<File> files )
            throws MavenReportException
    {
        Report report = null;
        RuleSetLoader rulesetLoader = RuleSetLoader.fromPmdConfig( pmdConfiguration )
                .warnDeprecated( true );
        try
        {
            // load the ruleset once to log out any deprecated rules as warnings
            rulesetLoader.loadFromResources( pmdConfiguration.getRuleSetPaths() );
        }
        catch ( RuleSetLoadException e1 )
        {
            throw new MavenReportException( "The ruleset could not be loaded", e1 );
        }

        try ( PmdAnalysis pmdAnalysis = PmdAnalysis.create( pmdConfiguration ) )
        {
            for ( File file : files )
            {
                pmdAnalysis.files().addFile( file.toPath() );
            }
            LOG.debug( "Executing PMD..." );
            report = pmdAnalysis.performAnalysisAndCollectReport();
            LOG.debug( "PMD finished. Found {} violations.", report.getViolations().size() );
        }
        catch ( Exception e )
        {
            String message = "Failure executing PMD: " + e.getLocalizedMessage();
            if ( !request.isSkipPmdError() )
            {
                throw new MavenReportException( message, e );
            }
            LOG.warn( message, e );

        }
        return report;
    }

    /**
     * Use the PMD XML renderer to create the XML report format used by the
     * check mojo later on.
     *
     * @param report
     * @throws MavenReportException
     */
    private void writeXmlReport( Report report ) throws MavenReportException
    {
        File targetFile = writeReport( report, new XMLRenderer( request.getOutputEncoding() ) );
        if ( request.isIncludeXmlInSite() )
        {
            File siteDir = new File( request.getReportOutputDirectory() );
            siteDir.mkdirs();
            try
            {
                FileUtils.copyFile( targetFile, new File( siteDir, "pmd.xml" ) );
            }
            catch ( IOException e )
            {
                throw new MavenReportException( e.getMessage(), e );
            }
        }
    }

    private File writeReport( Report report, Renderer r ) throws MavenReportException
    {
        if ( r == null )
        {
            return null;
        }

        File targetDir = new File( request.getTargetDirectory() );
        targetDir.mkdirs();
        String extension = r.defaultFileExtension();
        File targetFile = new File( targetDir, "pmd." + extension );
        LOG.debug( "Target PMD output file: {}", targetFile  );
        try ( Writer writer = new OutputStreamWriter( new FileOutputStream( targetFile ),
                request.getOutputEncoding() ) )
        {
            r.setWriter( writer );
            r.start();
            if ( report != null )
            {
                r.renderFileReport( report );
            }
            r.end();
            r.flush();
        }
        catch ( IOException ioe )
        {
            throw new MavenReportException( ioe.getMessage(), ioe );
        }

        return targetFile;
    }

    /**
     * Use the PMD renderers to render in any format aside from HTML and XML.
     *
     * @param report
     * @throws MavenReportException
     */
    private void writeFormattedReport( Report report )
            throws MavenReportException
    {
        Renderer renderer = createRenderer( request.getFormat(), request.getOutputEncoding() );
        writeReport( report, renderer );
    }

    /**
     * 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
     */
    public static Renderer createRenderer( String format, String outputEncoding ) throws MavenReportException
    {
        LOG.debug( "Renderer requested: {}", format );
        Renderer result = null;
        if ( "xml".equals( format ) )
        {
            result = new XMLRenderer( outputEncoding );
        }
        else if ( "txt".equals( format ) )
        {
            result = new TextRenderer();
        }
        else if ( "csv".equals( format ) )
        {
            result = new CSVRenderer();
        }
        else if ( "html".equals( format ) )
        {
            result = new HTMLRenderer();
        }
        else if ( !"".equals( format ) && !"none".equals( format ) )
        {
            try
            {
                result = (Renderer) Class.forName( format ).getConstructor().newInstance();
            }
            catch ( Exception e )
            {
                throw new MavenReportException(
                        "Can't find PMD custom format " + format + ": " + e.getClass().getName(), e );
            }
        }

        return result;
    }

    private Report removeExcludedViolations( Report report )
            throws MavenReportException
    {
        if ( report == null )
        {
            return null;
        }

        ExcludeViolationsFromFile excludeFromFile = new ExcludeViolationsFromFile();

        try
        {
            excludeFromFile.loadExcludeFromFailuresData( request.getExcludeFromFailureFile() );
        }
        catch ( MojoExecutionException e )
        {
            throw new MavenReportException( "Unable to load exclusions", e );
        }

        LOG.debug( "Removing excluded violations. Using {} configured exclusions.",
                excludeFromFile.countExclusions() );
        int violationsBefore = report.getViolations().size();

        Report filtered = report.filterViolations( new Predicate<RuleViolation>()
        {
            @Override
            public boolean test( RuleViolation ruleViolation )
            {
                return !excludeFromFile.isExcludedFromFailure( ruleViolation );
            }
        } );

        int numberOfExcludedViolations = violationsBefore - filtered.getViolations().size();
        LOG.debug( "Excluded {} violations.", numberOfExcludedViolations );
        return filtered;
    }
}
