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.
 *
 * @version $Id$
 */
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 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 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, use "error" as default value (as is 
                // done where the rule severity is displayed otherwise we miscount error violations)
                String configSeverity = getConfigAttribute( childConfig, null, "severity", "error" );

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

                if ( violations > 0 ) // forget rules without violations
                {
                    String category = RuleUtil.getCategory( lastMatchedEvent );

                    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;
        }
    }

}
