package org.apache.maven.plugins.surefire.report;

/*
 * 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.text.NumberFormat;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.maven.doxia.markup.HtmlMarkup;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
import org.apache.maven.doxia.util.DoxiaUtils;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.reporting.MavenReportException;

import static org.apache.maven.doxia.markup.HtmlMarkup.A;
import static org.apache.maven.doxia.sink.Sink.JUSTIFY_LEFT;
import static org.apache.maven.doxia.sink.SinkEventAttributes.CLASS;
import static org.apache.maven.doxia.sink.SinkEventAttributes.HREF;
import static org.apache.maven.doxia.sink.SinkEventAttributes.ID;
import static org.apache.maven.doxia.sink.SinkEventAttributes.NAME;
import static org.apache.maven.doxia.sink.SinkEventAttributes.STYLE;
import static org.apache.maven.doxia.sink.SinkEventAttributes.TYPE;

/**
 * This generator creates HTML Report from Surefire and Failsafe XML Report.
 */
public final class SurefireReportGenerator
{
    private static final int LEFT = JUSTIFY_LEFT;
    private static final Object[] TAG_TYPE_START = { HtmlMarkup.TAG_TYPE_START };
    private static final Object[] TAG_TYPE_END = { HtmlMarkup.TAG_TYPE_END };

    private final SurefireReportParser report;
    private final boolean showSuccess;
    private final String xrefLocation;
    private List<ReportTestSuite> testSuites;

    public SurefireReportGenerator( List<File> reportsDirectories, Locale locale, boolean showSuccess,
                                    String xrefLocation, ConsoleLogger consoleLogger )
    {
        report = new SurefireReportParser( reportsDirectories, locale, consoleLogger );
        this.showSuccess = showSuccess;
        this.xrefLocation = xrefLocation;
    }

    public void doGenerateReport( LocalizedProperties bundle, Sink sink )
        throws MavenReportException
    {
        testSuites = report.parseXMLReportFiles();

        sink.head();

        sink.title();
        sink.text( bundle.getReportHeader() );
        sink.title_();

        sink.head_();

        sink.body();

        SinkEventAttributeSet atts = new SinkEventAttributeSet();
        atts.addAttribute( TYPE, "application/javascript" );
        sink.unknown( "script", new Object[]{ HtmlMarkup.TAG_TYPE_START }, atts );
        sink.unknown( "cdata", new Object[]{ HtmlMarkup.CDATA_TYPE, javascriptToggleDisplayCode() }, null );
        sink.unknown( "script", new Object[]{ HtmlMarkup.TAG_TYPE_END }, null );

        sink.section1();
        sink.sectionTitle1();
        sink.text( bundle.getReportHeader() );
        sink.sectionTitle1_();
        sink.section1_();

        constructSummarySection( bundle, sink );

        Map<String, List<ReportTestSuite>> suitePackages = report.getSuitesGroupByPackage( testSuites );
        if ( !suitePackages.isEmpty() )
        {
            constructPackagesSection( bundle, sink, suitePackages );
        }

        if ( !testSuites.isEmpty() )
        {
            constructTestCasesSection( bundle, sink );
        }

        List<ReportTestCase> failureList = report.getFailureDetails( testSuites );
        if ( !failureList.isEmpty() )
        {
            constructFailureDetails( sink, bundle, failureList );
        }

        sink.body_();

        sink.flush();

        sink.close();
    }

    private void constructSummarySection( LocalizedProperties bundle, Sink sink )
    {
        Map<String, String> summary = report.getSummary( testSuites );

        sink.section1();
        sink.sectionTitle1();
        sink.text( bundle.getReportLabelSummary() );
        sink.sectionTitle1_();

        sinkAnchor( sink, "Summary" );

        constructHotLinks( sink, bundle );

        sinkLineBreak( sink );

        sink.table();

        sink.tableRows( new int[]{ LEFT, LEFT, LEFT, LEFT, LEFT, LEFT }, true );

        sink.tableRow();

        sinkHeader( sink, bundle.getReportLabelTests() );

        sinkHeader( sink, bundle.getReportLabelErrors() );

        sinkHeader( sink, bundle.getReportLabelFailures() );

        sinkHeader( sink, bundle.getReportLabelSkipped() );

        sinkHeader( sink, bundle.getReportLabelSuccessRate() );

        sinkHeader( sink, bundle.getReportLabelTime() );

        sink.tableRow_();

        sink.tableRow();

        sinkCell( sink, summary.get( "totalTests" ) );

        sinkCell( sink, summary.get( "totalErrors" ) );

        sinkCell( sink, summary.get( "totalFailures" ) );

        sinkCell( sink, summary.get( "totalSkipped" ) );

        sinkCell( sink, summary.get( "totalPercentage" ) + "%" );

        sinkCell( sink, summary.get( "totalElapsedTime" ) );

        sink.tableRow_();

        sink.tableRows_();

        sink.table_();

        sink.lineBreak();

        sink.paragraph();
        sink.text( bundle.getReportTextNode1() );
        sink.paragraph_();

        sinkLineBreak( sink );

        sink.section1_();
    }

    private void constructPackagesSection( LocalizedProperties bundle, Sink sink,
                                           Map<String, List<ReportTestSuite>> suitePackages )
    {
        NumberFormat numberFormat = report.getNumberFormat();

        sink.section1();
        sink.sectionTitle1();
        sink.text( bundle.getReportLabelPackageList() );
        sink.sectionTitle1_();

        sinkAnchor( sink, "Package_List" );

        constructHotLinks( sink, bundle );

        sinkLineBreak( sink );

        sink.table();

        sink.tableRows( new int[]{ LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT }, true );

        sink.tableRow();

        sinkHeader( sink, bundle.getReportLabelPackage() );

        sinkHeader( sink, bundle.getReportLabelTests() );

        sinkHeader( sink, bundle.getReportLabelErrors() );

        sinkHeader( sink, bundle.getReportLabelFailures() );

        sinkHeader( sink, bundle.getReportLabelSkipped() );

        sinkHeader( sink, bundle.getReportLabelSuccessRate() );

        sinkHeader( sink, bundle.getReportLabelTime() );

        sink.tableRow_();

        for ( Map.Entry<String, List<ReportTestSuite>> entry : suitePackages.entrySet() )
        {
            sink.tableRow();

            String packageName = entry.getKey();

            List<ReportTestSuite> testSuiteList = entry.getValue();

            Map<String, String> packageSummary = report.getSummary( testSuiteList );

            sinkCellLink( sink, packageName, "#" + packageName );

            sinkCell( sink, packageSummary.get( "totalTests" ) );

            sinkCell( sink, packageSummary.get( "totalErrors" ) );

            sinkCell( sink, packageSummary.get( "totalFailures" ) );

            sinkCell( sink, packageSummary.get( "totalSkipped" ) );

            sinkCell( sink, packageSummary.get( "totalPercentage" ) + "%" );

            sinkCell( sink, packageSummary.get( "totalElapsedTime" ) );

            sink.tableRow_();
        }

        sink.tableRows_();

        sink.table_();

        sink.lineBreak();

        sink.paragraph();
        sink.text( bundle.getReportTextNode2() );
        sink.paragraph_();

        for ( Map.Entry<String, List<ReportTestSuite>> entry : suitePackages.entrySet() )
        {
            String packageName = entry.getKey();

            List<ReportTestSuite> testSuiteList = entry.getValue();

            sink.section2();
            sink.sectionTitle2();
            sink.text( packageName );
            sink.sectionTitle2_();

            sinkAnchor( sink, packageName );

            boolean showTable = false;

            for ( ReportTestSuite suite : testSuiteList )
            {
                if ( showSuccess || suite.getNumberOfErrors() != 0 || suite.getNumberOfFailures() != 0 )
                {
                    showTable = true;

                    break;
                }
            }

            if ( showTable )
            {
                sink.table();

                sink.tableRows( new int[]{ LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT, LEFT }, true );

                sink.tableRow();

                sinkHeader( sink, "" );

                sinkHeader( sink, bundle.getReportLabelClass() );

                sinkHeader( sink, bundle.getReportLabelTests() );

                sinkHeader( sink, bundle.getReportLabelErrors() );

                sinkHeader( sink, bundle.getReportLabelFailures() );

                sinkHeader( sink, bundle.getReportLabelSkipped() );

                sinkHeader( sink, bundle.getReportLabelSuccessRate() );

                sinkHeader( sink, bundle.getReportLabelTime() );

                sink.tableRow_();

                for ( ReportTestSuite suite : testSuiteList )
                {
                    if ( showSuccess || suite.getNumberOfErrors() != 0 || suite.getNumberOfFailures() != 0 )
                    {
                        constructTestSuiteSection( sink, numberFormat, suite );
                    }
                }

                sink.tableRows_();

                sink.table_();
            }

            sink.section2_();
        }

        sinkLineBreak( sink );

        sink.section1_();
    }

    private void constructTestSuiteSection( Sink sink, NumberFormat numberFormat, ReportTestSuite suite )
    {
        sink.tableRow();

        sink.tableCell();

        sink.link( "#" + suite.getPackageName() + '.' + suite.getName() );

        if ( suite.getNumberOfErrors() > 0 )
        {
            sinkIcon( "error", sink );
        }
        else if ( suite.getNumberOfFailures() > 0 )
        {
            sinkIcon( "junit.framework", sink );
        }
        else if ( suite.getNumberOfSkipped() > 0 )
        {
            sinkIcon( "skipped", sink );
        }
        else
        {
            sinkIcon( "success", sink );
        }

        sink.link_();

        sink.tableCell_();

        sinkCellLink( sink, suite.getName(), "#" + suite.getPackageName() + '.' + suite.getName() );

        sinkCell( sink, Integer.toString( suite.getNumberOfTests() ) );

        sinkCell( sink, Integer.toString( suite.getNumberOfErrors() ) );

        sinkCell( sink, Integer.toString( suite.getNumberOfFailures() ) );

        sinkCell( sink, Integer.toString( suite.getNumberOfSkipped() ) );

        String percentage = report.computePercentage( suite.getNumberOfTests(), suite.getNumberOfErrors(),
                                                      suite.getNumberOfFailures(), suite.getNumberOfSkipped() );
        sinkCell( sink, percentage + "%" );

        sinkCell( sink, numberFormat.format( suite.getTimeElapsed() ) );

        sink.tableRow_();
    }

    private void constructTestCasesSection( LocalizedProperties bundle, Sink sink )
    {
        NumberFormat numberFormat = report.getNumberFormat();

        sink.section1();
        sink.sectionTitle1();
        sink.text( bundle.getReportLabelTestCases() );
        sink.sectionTitle1_();

        sinkAnchor( sink, "Test_Cases" );

        constructHotLinks( sink, bundle );

        for ( ReportTestSuite suite : testSuites )
        {
            List<ReportTestCase> testCases = suite.getTestCases();

            if ( !testCases.isEmpty() )
            {
                sink.section2();
                sink.sectionTitle2();
                sink.text( suite.getName() );
                sink.sectionTitle2_();

                sinkAnchor( sink, suite.getPackageName() + '.' + suite.getName() );

                boolean showTable = false;

                for ( ReportTestCase testCase : testCases )
                {
                    if ( !testCase.isSuccessful() || showSuccess )
                    {
                        showTable = true;

                        break;
                    }
                }

                if ( showTable )
                {
                    sink.table();

                    sink.tableRows( new int[]{ LEFT, LEFT, LEFT }, true );

                    for ( ReportTestCase testCase : testCases )
                    {
                        if ( !testCase.isSuccessful() || showSuccess )
                        {
                            constructTestCaseSection( sink, numberFormat, testCase );
                        }
                    }

                    sink.tableRows_();

                    sink.table_();
                }

                sink.section2_();
            }
        }

        sinkLineBreak( sink );

        sink.section1_();
    }

    private static void constructTestCaseSection( Sink sink, NumberFormat numberFormat, ReportTestCase testCase )
    {
        sink.tableRow();

        sink.tableCell();

        if ( testCase.getFailureType() != null )
        {
            sink.link( "#" + toHtmlId( testCase.getFullName() ) );

            sinkIcon( testCase.getFailureType(), sink );

            sink.link_();
        }
        else
        {
            sinkIcon( "success", sink );
        }

        sink.tableCell_();

        if ( !testCase.isSuccessful() )
        {
            sink.tableCell();

            sinkAnchor( sink, "TC_" + toHtmlId( testCase.getFullName() ) );

            sinkLink( sink, testCase.getName(), "#" + toHtmlId( testCase.getFullName() ) );

            SinkEventAttributeSet atts = new SinkEventAttributeSet();
            atts.addAttribute( CLASS, "detailToggle" );
            atts.addAttribute( STYLE, "display:inline" );
            sink.unknown( "div", TAG_TYPE_START, atts );

            sinkLink( sink, "javascript:toggleDisplay('" + toHtmlId( testCase.getFullName() ) + "');" );

            atts = new SinkEventAttributeSet();
            atts.addAttribute( STYLE, "display:inline;" );
            atts.addAttribute( ID, toHtmlId( testCase.getFullName() ) + "-off" );
            sink.unknown( "span", TAG_TYPE_START, atts );
            sink.text( " + " );
            sink.unknown( "span", TAG_TYPE_END, null );

            atts = new SinkEventAttributeSet();
            atts.addAttribute( STYLE, "display:none;" );
            atts.addAttribute( ID, toHtmlId( testCase.getFullName() ) + "-on" );
            sink.unknown( "span", TAG_TYPE_START, atts );
            sink.text( " - " );
            sink.unknown( "span", TAG_TYPE_END, null );

            sink.text( "[ Detail ]" );
            sinkLink_( sink );

            sink.unknown( "div", TAG_TYPE_END, null );

            sink.tableCell_();
        }
        else
        {
            sinkCellAnchor( sink, testCase.getName(), "TC_" + toHtmlId( testCase.getFullName() ) );
        }

        sinkCell( sink, numberFormat.format( testCase.getTime() ) );

        sink.tableRow_();

        if ( !testCase.isSuccessful() )
        {
            sink.tableRow();

            sinkCell( sink, "" );
            sinkCell( sink, testCase.getFailureMessage() );
            sinkCell( sink, "" );
            sink.tableRow_();

            String detail = testCase.getFailureDetail();
            if ( detail != null )
            {
                sink.tableRow();
                sinkCell( sink, "" );

                sink.tableCell();
                SinkEventAttributeSet atts = new SinkEventAttributeSet();
                atts.addAttribute( ID, toHtmlId( testCase.getFullName() ) + toHtmlIdFailure( testCase ) );
                atts.addAttribute( STYLE, "display:none;" );
                sink.unknown( "div", TAG_TYPE_START, atts );

                sink.verbatim( null );
                sink.text( detail );
                sink.verbatim_();

                sink.unknown( "div", TAG_TYPE_END, null );
                sink.tableCell_();

                sinkCell( sink, "" );

                sink.tableRow_();
            }
        }
    }

    private static String toHtmlId( String id )
    {
        return DoxiaUtils.isValidId( id ) ? id : DoxiaUtils.encodeId( id, true );
    }

    private void constructFailureDetails( Sink sink, LocalizedProperties bundle, List<ReportTestCase> failures )
    {
        sink.section1();
        sink.sectionTitle1();
        sink.text( bundle.getReportLabelFailureDetails() );
        sink.sectionTitle1_();

        sinkAnchor( sink, "Failure_Details" );

        constructHotLinks( sink, bundle );

        sinkLineBreak( sink );

        sink.table();

        sink.tableRows( new int[]{ LEFT, LEFT }, true );

        for ( ReportTestCase tCase : failures )
        {
            sink.tableRow();

            sink.tableCell();

            String type = tCase.getFailureType();

            sinkIcon( type, sink );

            sink.tableCell_();

            sinkCellAnchor( sink, tCase.getName(), toHtmlId( tCase.getFullName() ) );

            sink.tableRow_();

            String message = tCase.getFailureMessage();

            sink.tableRow();

            sinkCell( sink, "" );

            sinkCell( sink, message == null ? type : type + ": " + message );

            sink.tableRow_();

            String detail = tCase.getFailureDetail();
            if ( detail != null )
            {
                sink.tableRow();

                sinkCell( sink, "" );

                sink.tableCell();
                SinkEventAttributeSet atts = new SinkEventAttributeSet();
                atts.addAttribute( ID, tCase.getName() + toHtmlIdFailure( tCase ) );
                sink.unknown( "div", TAG_TYPE_START, atts );

                String fullClassName = tCase.getFullClassName();
                String errorLineNumber = tCase.getFailureErrorLine();
                if ( xrefLocation != null )
                {
                    String path = fullClassName.replace( '.', '/' );
                    sink.link( xrefLocation + "/" + path + ".html#L" + errorLineNumber );
                }
                sink.text( fullClassName + ":" + errorLineNumber );

                if ( xrefLocation != null )
                {
                    sink.link_();
                }
                sink.unknown( "div", TAG_TYPE_END, null );

                sink.tableCell_();

                sink.tableRow_();
            }
        }

        sink.tableRows_();

        sink.table_();

        sinkLineBreak( sink );

        sink.section1_();
    }

    private void constructHotLinks( Sink sink, LocalizedProperties bundle )
    {
        if ( !testSuites.isEmpty() )
        {
            sink.paragraph();

            sink.text( "[" );
            sinkLink( sink, bundle.getReportLabelSummary(), "#Summary" );
            sink.text( "]" );

            sink.text( " [" );
            sinkLink( sink, bundle.getReportLabelPackageList(), "#Package_List" );
            sink.text( "]" );

            sink.text( " [" );
            sinkLink( sink, bundle.getReportLabelTestCases(), "#Test_Cases" );
            sink.text( "]" );

            sink.paragraph_();
        }
    }

    private static String toHtmlIdFailure( ReportTestCase tCase )
    {
        return tCase.hasError() ? "-error" : "-failure";
    }

    private static void sinkLineBreak( Sink sink )
    {
        sink.lineBreak();
    }

    private static void sinkIcon( String type, Sink sink )
    {
        sink.figure();

        if ( type.startsWith( "junit.framework" ) || "skipped".equals( type ) )
        {
            sink.figureGraphics( "images/icon_warning_sml.gif" );
        }
        else if ( type.startsWith( "success" ) )
        {
            sink.figureGraphics( "images/icon_success_sml.gif" );
        }
        else
        {
            sink.figureGraphics( "images/icon_error_sml.gif" );
        }

        sink.figure_();
    }

    private static void sinkHeader( Sink sink, String header )
    {
        sink.tableHeaderCell();
        sink.text( header );
        sink.tableHeaderCell_();
    }

    private static void sinkCell( Sink sink, String text )
    {
        sink.tableCell();
        sink.text( text );
        sink.tableCell_();
    }

    private static void sinkLink( Sink sink, String text, String link )
    {
        sink.link( link );
        sink.text( text );
        sink.link_();
    }

    private static void sinkCellLink( Sink sink, String text, String link )
    {
        sink.tableCell();
        sinkLink( sink, text, link );
        sink.tableCell_();
    }

    private static void sinkCellAnchor( Sink sink, String text, String anchor )
    {
        sink.tableCell();
        sinkAnchor( sink, anchor );
        sink.text( text );
        sink.tableCell_();
    }

    private static void sinkAnchor( Sink sink, String anchor )
    {
        // Dollar '$' for nested classes is not valid character in sink.anchor() and therefore it is ignored
        // https://issues.apache.org/jira/browse/SUREFIRE-1443
        sink.unknown( A.toString(), TAG_TYPE_START, new SinkEventAttributeSet( NAME, anchor ) );
        sink.unknown( A.toString(), TAG_TYPE_END, null );
    }

    private static void sinkLink( Sink sink, String href )
    {
        // The "'" argument in this JavaScript function would be escaped to "&apos;"
        // sink.link( "javascript:toggleDisplay('" + toHtmlId( testCase.getFullName() ) + "');" );
        sink.unknown( A.toString(), TAG_TYPE_START, new SinkEventAttributeSet( HREF, href ) );
    }

    @SuppressWarnings( "checkstyle:methodname" )
    private static void sinkLink_( Sink sink )
    {
        sink.unknown( A.toString(), TAG_TYPE_END, null );
    }

    private static String javascriptToggleDisplayCode()
    {

        // the javascript code is emitted within a commented CDATA section
        // so we have to start with a newline and comment the CDATA closing in the end

        return "\n" + "function toggleDisplay(elementId) {\n"
                + " var elm = document.getElementById(elementId + '-error');\n"
                + " if (elm == null) {\n"
                + "  elm = document.getElementById(elementId + '-failure');\n"
                + " }\n"
                + " if (elm && typeof elm.style != \"undefined\") {\n"
                + "  if (elm.style.display == \"none\") {\n"
                + "   elm.style.display = \"\";\n"
                + "   document.getElementById(elementId + '-off').style.display = \"none\";\n"
                + "   document.getElementById(elementId + '-on').style.display = \"inline\";\n"
                + "  } else if (elm.style.display == \"\") {"
                + "   elm.style.display = \"none\";\n"
                + "   document.getElementById(elementId + '-off').style.display = \"inline\";\n"
                + "   document.getElementById(elementId + '-on').style.display = \"none\";\n"
                + "  } \n"
                + " } \n"
                + " }\n"
                + "//";
    }
}
