/*
 * 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.
 */
package org.apache.maven.plugins.pmd;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;

import net.sourceforge.pmd.RulePriority;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.pmd.model.ProcessingError;
import org.apache.maven.plugins.pmd.model.SuppressedViolation;
import org.apache.maven.plugins.pmd.model.Violation;
import org.codehaus.plexus.util.StringUtils;

/**
 * Render the PMD violations into Doxia events.
 *
 * @author Brett Porter
 * @version $Id$
 */
public class PmdReportGenerator {
    private Log log;

    private Sink sink;

    private String currentFilename;

    private ResourceBundle bundle;

    private Set<Violation> violations = new HashSet<>();

    private List<SuppressedViolation> suppressedViolations = new ArrayList<>();

    private List<ProcessingError> processingErrors = new ArrayList<>();

    private boolean aggregate;

    private boolean renderRuleViolationPriority;

    private boolean renderViolationsByPriority;

    private Map<File, PmdFileInfo> files;

    // private List<Metric> metrics = new ArrayList<Metric>();

    public PmdReportGenerator(Log log, Sink sink, ResourceBundle bundle, boolean aggregate) {
        this.log = log;
        this.sink = sink;
        this.bundle = bundle;
        this.aggregate = aggregate;
    }

    private String getTitle() {
        return bundle.getString("report.pmd.title");
    }

    public void setViolations(Collection<Violation> violations) {
        this.violations = new HashSet<>(violations);
    }

    public List<Violation> getViolations() {
        return new ArrayList<>(violations);
    }

    public void setSuppressedViolations(Collection<SuppressedViolation> suppressedViolations) {
        this.suppressedViolations = new ArrayList<>(suppressedViolations);
    }

    public void setProcessingErrors(Collection<ProcessingError> errors) {
        this.processingErrors = new ArrayList<>(errors);
    }

    public List<ProcessingError> getProcessingErrors() {
        return processingErrors;
    }

    // public List<Metric> getMetrics()
    // {
    // return metrics;
    // }
    //
    // public void setMetrics( List<Metric> metrics )
    // {
    // this.metrics = metrics;
    // }

    private String shortenFilename(String filename, PmdFileInfo fileInfo) {
        String result = filename;
        if (fileInfo != null && fileInfo.getSourceDirectory() != null) {
            result = StringUtils.substring(
                    result, fileInfo.getSourceDirectory().getAbsolutePath().length() + 1);
        }
        return StringUtils.replace(result, "\\", "/");
    }

    private String makeFileSectionName(String filename, PmdFileInfo fileInfo) {
        if (aggregate && fileInfo != null && fileInfo.getProject() != null) {
            return fileInfo.getProject().getName() + " - " + filename;
        }
        return filename;
    }

    private PmdFileInfo determineFileInfo(String filename) throws IOException {
        File canonicalFilename = new File(filename).getCanonicalFile();
        PmdFileInfo fileInfo = files.get(canonicalFilename);
        if (fileInfo == null) {
            log.warn("Couldn't determine PmdFileInfo for file " + filename + " (canonical: " + canonicalFilename
                    + "). XRef links won't be available.");
        }

        return fileInfo;
    }

    private void startFileSection(int level, String currentFilename, PmdFileInfo fileInfo) {
        sink.section(level, null);
        sink.sectionTitle(level, null);

        // prepare the filename
        this.currentFilename = shortenFilename(currentFilename, fileInfo);

        sink.text(makeFileSectionName(this.currentFilename, fileInfo));
        sink.sectionTitle_(level);

        sink.table();
        sink.tableRows(null, false);
        sink.tableRow();
        sink.tableHeaderCell();
        sink.text(bundle.getString("report.pmd.column.rule"));
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.text(bundle.getString("report.pmd.column.violation"));
        sink.tableHeaderCell_();
        if (this.renderRuleViolationPriority) {
            sink.tableHeaderCell();
            sink.text(bundle.getString("report.pmd.column.priority"));
            sink.tableHeaderCell_();
        }
        sink.tableHeaderCell();
        sink.text(bundle.getString("report.pmd.column.line"));
        sink.tableHeaderCell_();
        sink.tableRow_();
    }

    private void endFileSection(int level) {
        sink.tableRows_();
        sink.table_();
        sink.section_(level);
    }

    private void addRuleName(Violation ruleViolation) {
        boolean hasUrl = StringUtils.isNotBlank(ruleViolation.getExternalInfoUrl());

        if (hasUrl) {
            sink.link(ruleViolation.getExternalInfoUrl());
        }

        sink.text(ruleViolation.getRule());

        if (hasUrl) {
            sink.link_();
        }
    }

    private void processSingleRuleViolation(Violation ruleViolation, PmdFileInfo fileInfo) {
        sink.tableRow();
        sink.tableCell();
        addRuleName(ruleViolation);
        sink.tableCell_();
        sink.tableCell();
        sink.text(ruleViolation.getText());
        sink.tableCell_();

        if (this.renderRuleViolationPriority) {
            sink.tableCell();
            sink.text(String.valueOf(
                    RulePriority.valueOf(ruleViolation.getPriority()).getPriority()));
            sink.tableCell_();
        }

        sink.tableCell();

        int beginLine = ruleViolation.getBeginline();
        outputLineLink(beginLine, fileInfo);
        int endLine = ruleViolation.getEndline();
        if (endLine != beginLine) {
            sink.text("&#x2013;"); // \u2013 is a medium long dash character
            outputLineLink(endLine, fileInfo);
        }

        sink.tableCell_();
        sink.tableRow_();
    }

    // PMD might run the analysis multi-threaded, so the violations might be reported
    // out of order. We sort them here by filename and line number before writing them to
    // the report.
    private void renderViolations() throws IOException {
        sink.section1();
        sink.sectionTitle1();
        sink.text(bundle.getString("report.pmd.files"));
        sink.sectionTitle1_();

        // TODO files summary

        List<Violation> violations2 = new ArrayList<>(violations);
        renderViolationsTable(2, violations2);

        sink.section1_();
    }

    private void renderViolationsByPriority() throws IOException {
        if (!renderViolationsByPriority) {
            return;
        }

        boolean oldPriorityColumn = this.renderRuleViolationPriority;
        this.renderRuleViolationPriority = false;

        sink.section1();
        sink.sectionTitle1();
        sink.text(bundle.getString("report.pmd.violationsByPriority"));
        sink.sectionTitle1_();

        Map<RulePriority, List<Violation>> violationsByPriority = new HashMap<>();
        for (Violation violation : violations) {
            RulePriority priority = RulePriority.valueOf(violation.getPriority());
            List<Violation> violationSegment = violationsByPriority.get(priority);
            if (violationSegment == null) {
                violationSegment = new ArrayList<>();
                violationsByPriority.put(priority, violationSegment);
            }
            violationSegment.add(violation);
        }

        for (RulePriority priority : RulePriority.values()) {
            List<Violation> violationsWithPriority = violationsByPriority.get(priority);
            if (violationsWithPriority == null || violationsWithPriority.isEmpty()) {
                continue;
            }

            sink.section2();
            sink.sectionTitle2();
            sink.text(bundle.getString("report.pmd.priority") + " " + priority.getPriority());
            sink.sectionTitle2_();

            renderViolationsTable(3, violationsWithPriority);

            sink.section2_();
        }

        if (violations.isEmpty()) {
            sink.paragraph();
            sink.text(bundle.getString("report.pmd.noProblems"));
            sink.paragraph_();
        }

        sink.section1_();

        this.renderRuleViolationPriority = oldPriorityColumn;
    }

    private void renderViolationsTable(int level, List<Violation> violationSegment) throws IOException {
        Collections.sort(violationSegment, new Comparator<Violation>() {
            /** {@inheritDoc} */
            public int compare(Violation o1, Violation o2) {
                int filenames = o1.getFileName().compareTo(o2.getFileName());
                if (filenames == 0) {
                    return o1.getBeginline() - o2.getBeginline();
                } else {
                    return filenames;
                }
            }
        });

        boolean fileSectionStarted = false;
        String previousFilename = null;
        for (Violation ruleViolation : violationSegment) {
            String currentFn = ruleViolation.getFileName();
            PmdFileInfo fileInfo = determineFileInfo(currentFn);

            if (!currentFn.equalsIgnoreCase(previousFilename) && fileSectionStarted) {
                endFileSection(level);
                fileSectionStarted = false;
            }
            if (!fileSectionStarted) {
                startFileSection(level, currentFn, fileInfo);
                fileSectionStarted = true;
            }

            processSingleRuleViolation(ruleViolation, fileInfo);

            previousFilename = currentFn;
        }

        if (fileSectionStarted) {
            endFileSection(level);
        }
    }

    private void outputLineLink(int line, PmdFileInfo fileInfo) {
        String xrefLocation = null;
        if (fileInfo != null) {
            xrefLocation = fileInfo.getXrefLocation();
        }

        if (xrefLocation != null) {
            sink.link(xrefLocation + "/" + currentFilename.replaceAll("\\.java$", ".html") + "#L" + line);
        }
        sink.text(String.valueOf(line));
        if (xrefLocation != null) {
            sink.link_();
        }
    }

    // PMD might run the analysis multi-threaded, so the suppressed violations might be reported
    // out of order. We sort them here by filename before writing them to
    // the report.
    private void renderSuppressedViolations() throws IOException {
        sink.section1();
        sink.sectionTitle1();
        sink.text(bundle.getString("report.pmd.suppressedViolations.title"));
        sink.sectionTitle1_();

        Collections.sort(suppressedViolations, new Comparator<SuppressedViolation>() {
            @Override
            public int compare(SuppressedViolation o1, SuppressedViolation o2) {
                return o1.getFilename().compareTo(o2.getFilename());
            }
        });

        sink.table();
        sink.tableRows(null, false);
        sink.tableRow();
        sink.tableHeaderCell();
        sink.text(bundle.getString("report.pmd.suppressedViolations.column.filename"));
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.text(bundle.getString("report.pmd.suppressedViolations.column.ruleMessage"));
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.text(bundle.getString("report.pmd.suppressedViolations.column.suppressionType"));
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.text(bundle.getString("report.pmd.suppressedViolations.column.userMessage"));
        sink.tableHeaderCell_();
        sink.tableRow_();

        for (SuppressedViolation suppressedViolation : suppressedViolations) {
            String filename = suppressedViolation.getFilename();
            PmdFileInfo fileInfo = determineFileInfo(filename);
            filename = shortenFilename(filename, fileInfo);

            sink.tableRow();

            sink.tableCell();
            sink.text(filename);
            sink.tableCell_();

            sink.tableCell();
            sink.text(suppressedViolation.getRuleMessage());
            sink.tableCell_();

            sink.tableCell();
            sink.text(suppressedViolation.getSuppressionType());
            sink.tableCell_();

            sink.tableCell();
            sink.text(suppressedViolation.getUserMessage());
            sink.tableCell_();

            sink.tableRow_();
        }

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

    private void processProcessingErrors() throws IOException {
        // sort the problem by filename first, since PMD is executed multi-threaded
        // and might reports the results unsorted
        Collections.sort(processingErrors, new Comparator<ProcessingError>() {
            @Override
            public int compare(ProcessingError e1, ProcessingError e2) {
                return e1.getFilename().compareTo(e2.getFilename());
            }
        });

        sink.section1();
        sink.sectionTitle1();
        sink.text(bundle.getString("report.pmd.processingErrors.title"));
        sink.sectionTitle1_();

        sink.table();
        sink.tableRows(null, false);
        sink.tableRow();
        sink.tableHeaderCell();
        sink.text(bundle.getString("report.pmd.processingErrors.column.filename"));
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.text(bundle.getString("report.pmd.processingErrors.column.problem"));
        sink.tableHeaderCell_();
        sink.tableRow_();

        for (ProcessingError error : processingErrors) {
            processSingleProcessingError(error);
        }

        sink.tableRows_();
        sink.table_();

        sink.section1_();
    }

    private void processSingleProcessingError(ProcessingError error) throws IOException {
        String filename = error.getFilename();
        PmdFileInfo fileInfo = determineFileInfo(filename);
        filename = makeFileSectionName(shortenFilename(filename, fileInfo), fileInfo);

        sink.tableRow();
        sink.tableCell();
        sink.text(filename);
        sink.tableCell_();
        sink.tableCell();
        sink.text(error.getMsg());
        sink.verbatim(null);
        sink.rawText(error.getDetail());
        sink.verbatim_();
        sink.tableCell_();
        sink.tableRow_();
    }

    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("https://pmd.github.io");
        sink.text("PMD");
        sink.link_();
        sink.text(" " + AbstractPmdReport.getPmdVersion() + ".");
        sink.paragraph_();

        sink.section1_();

        // TODO overall summary
    }

    /*
     * 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 ( Metric met : metrics ) { sink.tableRow(); sink.tableCell(); sink.text(
     * met.getMetricName() ); sink.tableCell_(); sink.tableCell(); sink.text( String.valueOf( met.getCount() ) );
     * sink.tableCell_(); sink.tableCell(); sink.text( String.valueOf( met.getHighValue() ) ); sink.tableCell_();
     * sink.tableCell(); sink.text( String.valueOf( met.getLowValue() ) ); sink.tableCell_(); sink.tableCell();
     * sink.text( String.valueOf( met.getAverage() ) ); sink.tableCell_(); sink.tableRow_(); } sink.table_();
     * sink.section1_(); }
     */

    public void render() throws IOException {
        if (!violations.isEmpty()) {
            renderViolationsByPriority();

            renderViolations();
        } else {
            sink.paragraph();
            sink.text(bundle.getString("report.pmd.noProblems"));
            sink.paragraph_();
        }

        if (!suppressedViolations.isEmpty()) {
            renderSuppressedViolations();
        }

        if (!processingErrors.isEmpty()) {
            processProcessingErrors();
        }
    }

    public void endDocument() throws IOException {
        // The Metrics report useless with the current PMD metrics impl.
        // For instance, run the coupling ruleset and you will get a boatload
        // of excessive imports metrics, none of which is really any use.
        // TODO Determine if we are going to just ignore metrics.

        // processMetrics();

        sink.body_();

        sink.flush();

        sink.close();
    }

    public void setFiles(Map<File, PmdFileInfo> files) {
        this.files = files;
    }

    public void setRenderRuleViolationPriority(boolean renderRuleViolationPriority) {
        this.renderRuleViolationPriority = renderRuleViolationPriority;
    }

    public void setRenderViolationsByPriority(boolean renderViolationsByPriority) {
        this.renderViolationsByPriority = renderViolationsByPriority;
    }
}
