package org.apache.maven.plugin.pmd;

/*
 * Copyright 2005 The Apache Software Foundation.
 * 
 * Licensed 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.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;

import net.sourceforge.pmd.ReportListener;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.stat.Metric;

import org.codehaus.doxia.sink.Sink;
import org.codehaus.plexus.util.StringUtils;

/**
 * Handle events from PMD, converting them into Doxia events.
 *
 * @author Brett Porter
 * @version $Id: PmdReportListener.java,v 1.1.1.1 2005/02/17 07:16:22 brett Exp $
 */
public class PmdReportListener
    implements ReportListener
{
    private Sink sink;

    private String sourceDirectory;

    private String currentFilename;

    private boolean fileInitialized;

    private ResourceBundle bundle;

    private String xrefLocation;

    private List violations = new ArrayList();

    private List metrics = new ArrayList();

    public PmdReportListener( Sink sink, String sourceDirectory, ResourceBundle bundle )
    {
        this.sink = sink;
        this.sourceDirectory = sourceDirectory;
        this.bundle = bundle;
    }

    private String getTitle()
    {
        return bundle.getString( "report.pmd.title" );
    }

    public void ruleViolationAdded( RuleViolation ruleViolation )
    {
        if ( !fileInitialized )
        {
            sink.section2();
            sink.sectionTitle2();
            sink.text( currentFilename );
            sink.sectionTitle2_();

            sink.table();
            sink.tableRow();
            sink.tableHeaderCell();
            sink.text( bundle.getString( "report.pmd.column.violation" ) );
            sink.tableHeaderCell_();
            sink.tableHeaderCell();
            sink.text( bundle.getString( "report.pmd.column.line" ) );
            sink.tableHeaderCell_();
            sink.tableRow_();

            fileInitialized = true;
        }
        violations.add( ruleViolation );
    }

    // When dealing with multiple rulesets, the violations will get out of order
    // wrt their source line number.  We re-sort them before writing them to the report.
    private void processViolations()
    {
        Collections.sort( violations, new Comparator()
        {
            public int compare( Object o1, Object o2 )
            {
                return ( (RuleViolation) o1 ).getLine() - ( (RuleViolation) o2 ).getLine();
            }
        } );

        for ( Iterator it = violations.iterator(); it.hasNext(); )
        {
            RuleViolation ruleViolation = (RuleViolation) it.next();

            sink.tableRow();
            sink.tableCell();
            sink.text( ruleViolation.getDescription() );
            sink.tableCell_();
            sink.tableCell();

            if ( getXrefLocation() != null )
            {
                sink.link( getXrefLocation() + "/" + currentFilename.replaceAll( "\\.java$", ".html" ) + "#"
                    + ruleViolation.getLine() );
            }
            sink.text( String.valueOf( ruleViolation.getLine() ) );
            if ( getXrefLocation() != null )
            {
                sink.link_();
            }

            sink.tableCell_();
            sink.tableRow_();
        }
        violations.clear();
    }

    public void metricAdded( Metric metric )
    {
        if ( metric.getCount() != 0 )
        {
            // Skip metrics which have no data
            metrics.add( metric );
        }
    }

    public void beginDocument()
    {
        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.pmd.pmdlink" ) + " " );
        sink.link( "http://pmd.sourceforge.net/" );
        sink.text( "PMD" );
        sink.link_();
        sink.paragraph_();

        // TODO overall summary

        sink.section1_();
        sink.section1();
        sink.sectionTitle1();
        sink.text( bundle.getString( "report.pmd.files" ) );
        sink.sectionTitle1_();

        // TODO files summary
    }

    public void beginFile( File file )
    {
        currentFilename = StringUtils.substring( file.getAbsolutePath(), sourceDirectory.length() + 1 );
        currentFilename = StringUtils.replace( currentFilename, "\\", "/" );
        fileInitialized = false;
    }

    public void endFile( File file )
    {
        if ( fileInitialized )
        {
            processViolations();
            sink.table_();
            sink.section2_();
        }
    }

    private void processMetrics()
    {
        if ( metrics.size() == 0 )
        {
            return;
        }

        sink.section1();
        sink.sectionTitle1();
        sink.text( "Metrics" );
        sink.sectionTitle1_();

        sink.table();
        sink.tableRow();
        sink.tableHeaderCell();
        sink.text( "Name" );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.text( "Count" );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.text( "High" );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.text( "Low" );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.text( "Average" );
        sink.tableHeaderCell_();
        sink.tableRow_();

        for ( Iterator iter = metrics.iterator(); iter.hasNext(); )
        {
            Metric met = (Metric) iter.next();
            sink.tableRow();
            sink.tableCell();
            sink.text( met.getMetricName() );
            sink.tableCell_();
            sink.tableCell();
            sink.text( "" + met.getCount() );
            sink.tableCell_();
            sink.tableCell();
            sink.text( "" + met.getHighValue() );
            sink.tableCell_();
            sink.tableCell();
            sink.text( "" + met.getLowValue() );
            sink.tableCell_();
            sink.tableCell();
            sink.text( "" + met.getAverage() );
            sink.tableCell_();
            sink.tableRow_();
        }
        sink.table_();
        sink.section1_();
    }

    public void endDocument()
    {
        sink.section1_();

        processMetrics();

        sink.body_();

        sink.flush();

        sink.close();
    }

    public String getXrefLocation()
    {
        return xrefLocation;
    }

    public void setXrefLocation( String xrefLocation )
    {
        this.xrefLocation = xrefLocation;
    }
}
