package org.apache.maven.plugins.checkstyle;

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

import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.SinkEventAttributeSet;
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.tools.SiteTool;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.logging.SystemStreamLog;
import org.apache.maven.plugins.checkstyle.exec.CheckstyleResults;
import org.codehaus.plexus.util.StringUtils;

import com.puppycrawl.tools.checkstyle.api.AuditEvent;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import com.puppycrawl.tools.checkstyle.api.SeverityLevel;

/**
 * Generate a report based on CheckstyleResults.
 *
 *
 */
public class CheckstyleReportGenerator
{
    private Log log;

    private final File basedir;

    private final ResourceBundle bundle;

    private final Sink sink;

    private SeverityLevel severityLevel;

    private Configuration checkstyleConfig;

    private boolean enableRulesSummary;

    private boolean enableSeveritySummary;

    private boolean enableFilesSummary;

    private boolean skipEmptyViolationRules;

    private boolean enableRSS;

    private final SiteTool siteTool;

    private String xrefLocation;

    private List<String> treeWalkerNames = Collections.singletonList( "TreeWalker" );

    private final IconTool iconTool;

    private final String ruleset;

    public CheckstyleReportGenerator( Sink sink, ResourceBundle bundle, File basedir, SiteTool siteTool,
                                      String ruleset )
    {
        this.bundle = bundle;

        this.sink = sink;

        this.basedir = basedir;

        this.siteTool = siteTool;

        this.ruleset = ruleset;

        this.enableRulesSummary = true;
        this.enableSeveritySummary = true;
        this.enableFilesSummary = true;
        this.enableRSS = true;
        this.iconTool = new IconTool( sink, bundle );
    }

    public Log getLog()
    {
        if ( this.log == null )
        {
            this.log = new SystemStreamLog();
        }
        return this.log;
    }

    public void setLog( Log log )
    {
        this.log = log;
    }

    private String getTitle()
    {
        String title;

        if ( getSeverityLevel() == null )
        {
            title = bundle.getString( "report.checkstyle.title" );
        }
        else
        {
            title = bundle.getString( "report.checkstyle.severity_title" ) + severityLevel.getName();
        }

        return title;
    }

    public void generateReport( CheckstyleResults results )
    {
        doHeading();

        if ( getSeverityLevel() == null )
        {
            if ( enableSeveritySummary )
            {
                doSeveritySummary( results );
            }

            if ( enableFilesSummary )
            {
                doFilesSummary( results );
            }

            if ( enableRulesSummary )
            {
                doRulesSummary( results );
            }
        }

        doDetails( results );
        sink.body_();
        sink.flush();
        sink.close();
    }

    private void doHeading()
    {
        sink.head();
        sink.title();
        sink.text( getTitle() );
        sink.title_();
        sink.head_();

        sink.body();

        sink.section1();
        sink.sectionTitle1();
        sink.text( getTitle() );
        sink.sectionTitle1_();

        sink.paragraph();
        sink.text( bundle.getString( "report.checkstyle.checkstylelink" ) + " " );
        sink.link( "http://checkstyle.sourceforge.net/" );
        sink.text( "Checkstyle" );
        sink.link_();
        String version = getCheckstyleVersion();
        if ( version != null )
        {
            sink.text( " " );
            sink.text( version );
        }
        sink.text( " " );
        sink.text( String.format( bundle.getString( "report.checkstyle.ruleset" ), ruleset ) );
        sink.text( "." );

        if ( enableRSS )
        {
            sink.nonBreakingSpace();
            sink.link( "checkstyle.rss" );
            sink.figure();
            sink.figureCaption();
            sink.text( "rss feed" );
            sink.figureCaption_();
            sink.figureGraphics( "images/rss.png" );
            sink.figure_();
            sink.link_();
        }

        sink.paragraph_();
        sink.section1_();
    }

    /**
     * Get the value of the specified attribute from the Checkstyle configuration.
     * If parentConfigurations is non-null and non-empty, the parent
     * configurations are searched if the attribute cannot be found in the
     * current configuration. If the attribute is still not found, the
     * specified default value will be returned.
     *
     * @param config The current Checkstyle configuration
     * @param parentConfiguration The configuration of the parent of the current configuration
     * @param attributeName The name of the attribute
     * @param defaultValue The default value to use if the attribute cannot be found in any configuration
     * @return The value of the specified attribute
     */
    private String getConfigAttribute( Configuration config, ChainedItem<Configuration> parentConfiguration,
                                       String attributeName, String defaultValue )
    {
        String ret;
        try
        {
            ret = config.getAttribute( attributeName );
        }
        catch ( CheckstyleException e )
        {
            // Try to find the attribute in a parent, if there are any
            if ( parentConfiguration != null )
            {
                ret =
                    getConfigAttribute( parentConfiguration.value, parentConfiguration.parent, attributeName,
                                        defaultValue );
            }
            else
            {
                ret = defaultValue;
            }
        }
        return ret;
    }

    /**
     * Create the rules summary section of the report.
     *
     * @param results The results to summarize
     */
    private void doRulesSummary( CheckstyleResults results )
    {
        if ( checkstyleConfig == null )
        {
            return;
        }

        sink.section1();
        sink.sectionTitle1();
        sink.text( bundle.getString( "report.checkstyle.rules" ) );
        sink.sectionTitle1_();

        sink.table();

        sink.tableRow();
        sink.tableHeaderCell();
        sink.text( bundle.getString( "report.checkstyle.rule.category" ) );
        sink.tableHeaderCell_();

        sink.tableHeaderCell();
        sink.text( bundle.getString( "report.checkstyle.rule" ) );
        sink.tableHeaderCell_();

        sink.tableHeaderCell();
        sink.text( bundle.getString( "report.checkstyle.violations" ) );
        sink.tableHeaderCell_();

        sink.tableHeaderCell();
        sink.text( bundle.getString( "report.checkstyle.column.severity" ) );
        sink.tableHeaderCell_();

        sink.tableRow_();

        // Top level should be the checker.
        if ( "checker".equalsIgnoreCase( checkstyleConfig.getName() ) )
        {
            String category = null;
            for ( ConfReference ref: sortConfiguration( results ) )
            {
                doRuleRow( ref, results, category );

                category = ref.category;
            }
        }
        else
        {
            sink.tableRow();
            sink.tableCell();
            sink.text( bundle.getString( "report.checkstyle.norule" ) );
            sink.tableCell_();
            sink.tableRow_();
        }

        sink.table_();

        sink.section1_();
    }

    /**
     * Create a summary for one Checkstyle rule.
     *
     * @param ref The configuration reference for the row
     * @param results The results to summarize
     * @param previousCategory The previous row's category
     */
    private void doRuleRow( ConfReference ref, CheckstyleResults results, String previousCategory )
    {
        Configuration checkerConfig = ref.configuration;
        ChainedItem<Configuration> parentConfiguration = ref.parentConfiguration;
        String ruleName = checkerConfig.getName();

        sink.tableRow();

        // column 1: rule category
        sink.tableCell();
        String category = ref.category;
        if ( !category.equals( previousCategory ) )
        {
            sink.text( category );
        }
        sink.tableCell_();

        // column 2: Rule name + configured attributes
        sink.tableCell();
        if ( !"extension".equals( category ) )
        {
            sink.link( "http://checkstyle.sourceforge.net/config_" + category + ".html#" + ruleName );
            sink.text( ruleName );
            sink.link_();
        }
        else
        {
            sink.text( ruleName );
        }

        List<String> attribnames = new ArrayList<>( Arrays.asList( checkerConfig.getAttributeNames() ) );
        attribnames.remove( "severity" ); // special value (deserves unique column)
        if ( !attribnames.isEmpty() )
        {
            sink.list();
            for ( String name : attribnames )
            {
                sink.listItem();

                sink.text( name );

                String value = getConfigAttribute( checkerConfig, null, name, "" );
                // special case, Header.header and RegexpHeader.header
                if ( "header".equals( name ) && ( "Header".equals( ruleName ) || "RegexpHeader".equals( ruleName ) ) )
                {
                    String[] lines = StringUtils.split( value, "\\n" );
                    int linenum = 1;
                    for ( String line : lines )
                    {
                        sink.lineBreak();
                        sink.rawText( "<span style=\"color: gray\">" );
                        sink.text( linenum + ":" );
                        sink.rawText( "</span>" );
                        sink.nonBreakingSpace();
                        sink.monospaced();
                        sink.text( line );
                        sink.monospaced_();
                        linenum++;
                    }
                }
                else if ( "headerFile".equals( name ) && "RegexpHeader".equals( ruleName ) )
                {
                    sink.text( ": " );
                    sink.monospaced();
                    sink.text( "\"" );
                    if ( basedir != null )
                    {
                        // Make the headerFile value relative to ${basedir}
                        String path = siteTool.getRelativePath( value, basedir.getAbsolutePath() );
                        sink.text( path.replace( '\\', '/' ) );
                    }
                    else
                    {
                        sink.text( value );
                    }
                    sink.text( "\"" );
                    sink.monospaced_();
                }
                else
                {
                    sink.text( ": " );
                    sink.monospaced();
                    sink.text( "\"" );
                    sink.text( value );
                    sink.text( "\"" );
                    sink.monospaced_();
                }
                sink.listItem_();
            }
            sink.list_();
        }

        sink.tableCell_();

        // column 3: rule violation count
        sink.tableCell();
        sink.text( String.valueOf( ref.violations ) );
        sink.tableCell_();

        // column 4: severity
        sink.tableCell();
        // Grab the severity from the rule configuration, this time use error as default value
        // Also pass along all parent configurations, so that we can try to find the severity there
        String severity = getConfigAttribute( checkerConfig, parentConfiguration, "severity", "error" );
        iconTool.iconSeverity( severity, IconTool.TEXT_SIMPLE );
        sink.tableCell_();

        sink.tableRow_();
    }

    /**
     * Check if a violation matches a rule.
     *
     * @param event the violation to check
     * @param ruleName The name of the rule
     * @param expectedMessage A message that, if it's not null, will be matched to the message from the violation
     * @param expectedSeverity A severity that, if it's not null, will be matched to the severity from the violation
     * @return The number of rule violations
     */
    public boolean matchRule( AuditEvent event, String ruleName, String expectedMessage, String expectedSeverity )
    {
        if ( !ruleName.equals( RuleUtil.getName( event ) ) )
        {
            return false;
        }

        // check message too, for those that have a specific one.
        // like GenericIllegalRegexp and Regexp
        if ( expectedMessage != null )
        {
            // event.getMessage() uses java.text.MessageFormat in its implementation.
            // Read MessageFormat Javadoc about single quote:
            // http://java.sun.com/j2se/1.4.2/docs/api/java/text/MessageFormat.html
            String msgWithoutSingleQuote = StringUtils.replace( expectedMessage, "'", "" );

            if ( ! ( expectedMessage.equals( event.getMessage() )
                || msgWithoutSingleQuote.equals( event.getMessage() ) ) )
            {
                return false;
            }
        }
        // Check the severity. This helps to distinguish between
        // different configurations for the same rule, where each
        // configuration has a different severity, like JavadocMethod.
        // See also https://issues.apache.org/jira/browse/MCHECKSTYLE-41
        if ( expectedSeverity != null )
        {
            if ( !expectedSeverity.equals( event.getSeverityLevel().getName() ) )
            {
                return false;
            }
        }
        return true;
    }

    private void doSeveritySummary( CheckstyleResults results )
    {
        sink.section1();
        sink.sectionTitle1();
        sink.text( bundle.getString( "report.checkstyle.summary" ) );
        sink.sectionTitle1_();

        sink.table();

        sink.tableRow();
        sink.tableHeaderCell();
        sink.text( bundle.getString( "report.checkstyle.files" ) );
        sink.tableHeaderCell_();

        sink.tableHeaderCell();
        iconTool.iconInfo( IconTool.TEXT_TITLE );
        sink.tableHeaderCell_();

        sink.tableHeaderCell();
        iconTool.iconWarning( IconTool.TEXT_TITLE );
        sink.tableHeaderCell_();

        sink.tableHeaderCell();
        iconTool.iconError( IconTool.TEXT_TITLE );
        sink.tableHeaderCell_();
        sink.tableRow_();

        sink.tableRow();
        sink.tableCell();
        sink.text( String.valueOf( results.getFileCount() ) );
        sink.tableCell_();
        sink.tableCell();
        sink.text( String.valueOf( results.getSeverityCount( SeverityLevel.INFO ) ) );
        sink.tableCell_();
        sink.tableCell();
        sink.text( String.valueOf( results.getSeverityCount( SeverityLevel.WARNING ) ) );
        sink.tableCell_();
        sink.tableCell();
        sink.text( String.valueOf( results.getSeverityCount( SeverityLevel.ERROR ) ) );
        sink.tableCell_();
        sink.tableRow_();

        sink.table_();

        sink.section1_();
    }

    private void doFilesSummary( CheckstyleResults results )
    {
        sink.section1();
        sink.sectionTitle1();
        sink.text( bundle.getString( "report.checkstyle.files" ) );
        sink.sectionTitle1_();

        sink.table();

        sink.tableRow();
        sink.tableHeaderCell();
        sink.text( bundle.getString( "report.checkstyle.file" ) );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        iconTool.iconInfo( IconTool.TEXT_ABBREV );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        iconTool.iconWarning( IconTool.TEXT_ABBREV );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        iconTool.iconError( IconTool.TEXT_ABBREV );
        sink.tableHeaderCell_();
        sink.tableRow_();

        // Sort the files before writing them to the report
        List<String> fileList = new ArrayList<>( results.getFiles().keySet() );
        Collections.sort( fileList );

        for ( String filename : fileList )
        {
            List<AuditEvent> violations = results.getFileViolations( filename );
            if ( violations.isEmpty() )
            {
                // skip files without violations
                continue;
            }

            sink.tableRow();

            sink.tableCell();
            sink.link( "#" + filename.replace( '/', '.' ) );
            sink.text( filename );
            sink.link_();
            sink.tableCell_();

            sink.tableCell();
            sink.text( String.valueOf( results.getSeverityCount( violations, SeverityLevel.INFO ) ) );
            sink.tableCell_();

            sink.tableCell();
            sink.text( String.valueOf( results.getSeverityCount( violations, SeverityLevel.WARNING ) ) );
            sink.tableCell_();

            sink.tableCell();
            sink.text( String.valueOf( results.getSeverityCount( violations, SeverityLevel.ERROR ) ) );
            sink.tableCell_();

            sink.tableRow_();
        }

        sink.table_();
        sink.section1_();
    }

    private void doDetails( CheckstyleResults results )
    {

        sink.section1();
        sink.sectionTitle1();
        sink.text( bundle.getString( "report.checkstyle.details" ) );
        sink.sectionTitle1_();

        // Sort the files before writing their details to the report
        List<String> fileList = new ArrayList<>( results.getFiles().keySet() );
        Collections.sort( fileList );

        for ( String file : fileList )
        {
            List<AuditEvent> violations = results.getFileViolations( file );

            if ( violations.isEmpty() )
            {
                // skip files without violations
                continue;
            }

            sink.section2();
            SinkEventAttributes attrs = new SinkEventAttributeSet();
            attrs.addAttribute( SinkEventAttributes.ID, file.replace( '/', '.' ) );
            sink.sectionTitle( Sink.SECTION_LEVEL_2, attrs );
            sink.text( file );
            sink.sectionTitle_( Sink.SECTION_LEVEL_2 );

            sink.table();
            sink.tableRow();
            sink.tableHeaderCell();
            sink.text( bundle.getString( "report.checkstyle.column.severity" ) );
            sink.tableHeaderCell_();
            sink.tableHeaderCell();
            sink.text( bundle.getString( "report.checkstyle.rule.category" ) );
            sink.tableHeaderCell_();
            sink.tableHeaderCell();
            sink.text( bundle.getString( "report.checkstyle.rule" ) );
            sink.tableHeaderCell_();
            sink.tableHeaderCell();
            sink.text( bundle.getString( "report.checkstyle.column.message" ) );
            sink.tableHeaderCell_();
            sink.tableHeaderCell();
            sink.text( bundle.getString( "report.checkstyle.column.line" ) );
            sink.tableHeaderCell_();
            sink.tableRow_();

            doFileEvents( violations, file );

            sink.table_();
            sink.section2_();
        }

        sink.section1_();
    }

    private void doFileEvents( List<AuditEvent> eventList, String filename )
    {
        for ( AuditEvent event : eventList )
        {
            SeverityLevel level = event.getSeverityLevel();

            if ( ( getSeverityLevel() != null ) && !( getSeverityLevel() != level ) )
            {
                continue;
            }

            sink.tableRow();

            sink.tableCell();
            iconTool.iconSeverity( level.getName(), IconTool.TEXT_SIMPLE );
            sink.tableCell_();

            sink.tableCell();
            String category = RuleUtil.getCategory( event );
            if ( category != null )
            {
                sink.text( category );
            }
            sink.tableCell_();

            sink.tableCell();
            String ruleName = RuleUtil.getName( event );
            if ( ruleName != null )
            {
                sink.text( ruleName );
            }
            sink.tableCell_();

            sink.tableCell();
            sink.text( event.getMessage() );
            sink.tableCell_();

            sink.tableCell();

            int line = event.getLine();
            if ( getXrefLocation() != null && line != 0 )
            {
                sink.link( getXrefLocation() + "/" + filename.replaceAll( "\\.java$", ".html" ) + "#L"
                    + line );
                sink.text( String.valueOf( line ) );
                sink.link_();
            }
            else if ( line != 0 )
            {
                sink.text( String.valueOf( line ) );
            }
            sink.tableCell_();

            sink.tableRow_();
        }
    }

    public SeverityLevel getSeverityLevel()
    {
        return severityLevel;
    }

    public void setSeverityLevel( SeverityLevel severityLevel )
    {
        this.severityLevel = severityLevel;
    }

    public boolean isEnableRulesSummary()
    {
        return enableRulesSummary;
    }

    public void setEnableRulesSummary( boolean enableRulesSummary )
    {
        this.enableRulesSummary = enableRulesSummary;
    }

    public boolean isEnableSeveritySummary()
    {
        return enableSeveritySummary;
    }

    public void setEnableSeveritySummary( boolean enableSeveritySummary )
    {
        this.enableSeveritySummary = enableSeveritySummary;
    }

    public boolean isEnableFilesSummary()
    {
        return enableFilesSummary;
    }

    public void setEnableFilesSummary( boolean enableFilesSummary )
    {
        this.enableFilesSummary = enableFilesSummary;
    }

    public boolean isEnableRSS()
    {
        return enableRSS;
    }

    public void setEnableRSS( boolean enableRSS )
    {
        this.enableRSS = enableRSS;
    }

    public boolean isSkipEmptyViolationRules()
    {
        return skipEmptyViolationRules;
    }

    public void setSkipEmptyViolationRules( boolean showEmptyViolationRules )
    {
        this.skipEmptyViolationRules = showEmptyViolationRules;
    }

    public String getXrefLocation()
    {
        return xrefLocation;
    }

    public void setXrefLocation( String xrefLocation )
    {
        this.xrefLocation = xrefLocation;
    }

    public Configuration getCheckstyleConfig()
    {
        return checkstyleConfig;
    }

    public void setCheckstyleConfig( Configuration config )
    {
        this.checkstyleConfig = config;
    }

    public void setTreeWalkerNames( List<String> treeWalkerNames )
    {
        this.treeWalkerNames = treeWalkerNames;
    }

    public List<String> getTreeWalkerNames()
    {
        return treeWalkerNames;
    }

    /**
     * Get the effective Checkstyle version at runtime.
     * @return the MANIFEST implementation version of Checkstyle API package (can be <code>null</code>)
     */
    private String getCheckstyleVersion()
    {
        Package checkstyleApiPackage = Configuration.class.getPackage();

        return ( checkstyleApiPackage == null ) ? null : checkstyleApiPackage.getImplementationVersion();
    }

    public List<ConfReference> sortConfiguration( CheckstyleResults results )
    {
        List<ConfReference> result = new ArrayList<>();

        sortConfiguration( result, checkstyleConfig, null, results );

        Collections.sort( result );

        return result;
    }

    private void sortConfiguration( List<ConfReference> result, Configuration config,
                                    ChainedItem<Configuration> parent, CheckstyleResults results )
    {
        for ( Configuration childConfig : config.getChildren() )
        {
            String ruleName = childConfig.getName();

            if ( treeWalkerNames.contains( ruleName ) )
            {
                // special sub-case: TreeWalker is the parent of multiple rules, not an effective rule
                sortConfiguration( result, childConfig, new ChainedItem<>( config, parent ), results );
            }
            else
            {
                String fixedmessage = getConfigAttribute( childConfig, null, "message", null );
                // Grab the severity from the rule configuration. Do not set default value here as
                // it breaks our rule aggregate section entirely.  The counts are off but this is
                // not appropriate fix location per MCHECKSTYLE-365.
                String configSeverity = getConfigAttribute( childConfig, null, "severity", null );

                // count rule violations
                long violations = 0;
                for ( List<AuditEvent> errors : results.getFiles().values() )
                {
                    for ( AuditEvent event : errors )
                    {
                        if ( matchRule( event, ruleName, fixedmessage, configSeverity ) )
                        {
                            violations++;
                        }
                    }
                }

                if ( violations > 0 || !skipEmptyViolationRules ) // forget rules without violations when not requested
                {
                    String category = RuleUtil.getCategory( results.getModuleNameMap().get( ruleName ) );
                    if ( category != null )
                    {
                        result.add( new ConfReference( category, childConfig, parent, violations, result.size() ) );
                    }
                }
            }
        }
    }

    private static class ConfReference
        implements Comparable<ConfReference>
    {
        private final String category;
        private final Configuration configuration;
        private final ChainedItem<Configuration> parentConfiguration;
        private final long violations;
        private final int count;

        ConfReference( String category, Configuration configuration,
                              ChainedItem<Configuration> parentConfiguration, long violations, int count )
        {
            this.category = category;
            this.configuration = configuration;
            this.parentConfiguration = parentConfiguration;
            this.violations = violations;
            this.count = count;
        }

        public int compareTo( ConfReference o )
        {
            int compare = category.compareTo( o.category );
            if ( compare == 0 )
            {
                compare = configuration.getName().compareTo( o.configuration.getName() );
            }
            return ( compare == 0 ) ? ( o.count - count ) : compare;
        }
    }

    private static class ChainedItem<T>
    {
        private final ChainedItem<T> parent;

        private final T value;

        ChainedItem( T value, ChainedItem<T> parent )
        {
            this.parent = parent;
            this.value = value;
        }
    }

}
