/*
 * 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.felix.bundleplugin.baseline;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.reporting.MavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.codehaus.plexus.util.IOUtil;

import aQute.bnd.version.Version;

/**
 * BND Baseline report.
 *
 * @since 2.4.1
 */
@Mojo( name = "baseline-report", threadSafe = true,
       defaultPhase = LifecyclePhase.SITE)
public final class BaselineReport
    extends AbstractBaselinePlugin
    implements MavenReport
{

    /**
     * Specifies the directory where the report will be generated.
     */
    @Parameter(defaultValue = "${project.reporting.outputDirectory}")
    private File outputDirectory;

    private static final class Context {
        public Sink sink;

        public Locale locale;

        public int currentDepth = 0;
    }

    // AbstractBaselinePlugin events

    @Override
    protected Object init(final Object context)
    {
        failOnError = false;
        failOnWarning = false;

        final File baselineImagesDirectory = new File( outputDirectory, "images/baseline" );
        baselineImagesDirectory.mkdirs();

        for ( String resourceName : new String[]{ "access.gif",
                                                  "annotated.gif",
                                                  "annotation.gif",
                                                  "bundle.gif",
                                                  "class.gif",
                                                  "constant.gif",
                                                  "enum.gif",
                                                  "error.gif",
                                                  "extends.gif",
                                                  "field.gif",
                                                  "implements.gif",
                                                  "info.gif",
                                                  "interface.gif",
                                                  "method.gif",
                                                  "package.gif",
                                                  "resource.gif",
                                                  "return.gif",
                                                  "version.gif",
                                                  "warning.gif" } )
        {
            InputStream source = getClass().getResourceAsStream( resourceName );
            OutputStream target = null;
            File targetFile = new File( baselineImagesDirectory, resourceName );

            try
            {
                target = new FileOutputStream( targetFile );
                IOUtil.copy( source, target );
            }
            catch ( IOException e )
            {
                getLog().warn( "Impossible to copy " + resourceName + " image, maybe the site won't be properly rendered." );
            }
            finally
            {
                IOUtil.close( source );
                IOUtil.close( target );
            }
        }
        return context;
    }

    @Override
    protected void close(final Object context)
    {
        // nothing to do
    }

    @Override
    protected void startBaseline( final Object context, String generationDate, String bundleName,
            String currentVersion, String previousVersion )
    {
        final Context ctx = (Context)context;
        final Sink sink = ctx.sink;

        sink.head();
        sink.title();

        String title = getBundle( ctx.locale ).getString( "report.baseline.title" );
        sink.text( title );
        sink.title_();
        sink.head_();

        sink.body();

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

        sink.paragraph();
        sink.text( getBundle( ctx.locale ).getString( "report.baseline.bndlink" ) + " " );
        sink.link( "http://www.aqute.biz/Bnd/Bnd" );
        sink.text( "Bnd" );
        sink.link_();
        sink.text( "." );
        sink.paragraph_();

        sink.paragraph();
        sink.text( getBundle( ctx.locale ).getString( "report.baseline.bundle" ) + " " );
        sink.figure();
        sink.figureGraphics( "images/baseline/bundle.gif" );
        sink.figure_();
        sink.text( " " );
        sink.bold();
        sink.text( bundleName );
        sink.bold_();
        sink.listItem_();

        sink.paragraph();
        sink.text( getBundle( ctx.locale ).getString( "report.baseline.version.current" ) + " " );
        sink.bold();
        sink.text( currentVersion );
        sink.bold_();
        sink.paragraph_();

        sink.paragraph();
        sink.text( getBundle( ctx.locale ).getString( "report.baseline.version.comparison" ) + " " );
        sink.bold();
        sink.text( comparisonVersion );
        sink.bold_();
        sink.paragraph_();

        sink.paragraph();
        sink.text( getBundle( ctx.locale ).getString( "report.baseline.generationdate" ) + " " );
        sink.bold();
        sink.text( generationDate );
        sink.bold_();
        sink.paragraph_();

        sink.section1_();
    }

    @Override
    protected void startPackage( final Object context,
                                 boolean mismatch,
                                 String packageName,
                                 String shortDelta,
                                 String delta,
                                 Version newerVersion,
                                 Version olderVersion,
                                 Version suggestedVersion,
                                 DiffMessage diffMessage,
                                 Map<String,String> attributes )
    {
        final Context ctx = (Context)context;
        final Sink sink = ctx.sink;

        sink.list();

        sink.listItem();

        sink.figure();
        sink.figureGraphics( "./images/baseline/package.gif" );
        sink.figure_();
        sink.text( " " );
        sink.monospaced();
        sink.text( packageName );
        sink.monospaced_();

        if ( diffMessage != null )
        {
            sink.text( " " );
            sink.figure();
            sink.figureGraphics( "./images/baseline/" + diffMessage.getType().name() + ".gif" );
            sink.figure_();
            sink.text( " " );
            sink.italic();
            sink.text( diffMessage.getMessage() );
            sink.italic_();
            sink.text( " (newer version: " );
            sink.monospaced();
            sink.text( newerVersion.toString() );
            sink.monospaced_();
            sink.text( ", older version: " );
            sink.monospaced();
            sink.text( olderVersion.toString() );
            if ( suggestedVersion != null )
            {
                sink.monospaced_();
                sink.text( ", suggested version: " );
                sink.monospaced();
                sink.text( suggestedVersion.toString() );
            }
            sink.monospaced_();
            sink.text( ")" );
        }
    }

    @Override
    protected void startDiff( final Object context,
                              int depth,
                              String type,
                              String name,
                              String delta,
                              String shortDelta )
    {
        final Context ctx = (Context)context;
        final Sink sink = ctx.sink;

        if ( ctx.currentDepth < depth )
        {
            sink.list();
        }

        ctx.currentDepth = depth;

        sink.listItem();
        sink.figure();
        sink.figureGraphics( "images/baseline/" + type + ".gif" );
        sink.figure_();
        sink.text( " " );

        sink.monospaced();
        sink.text( name );
        sink.monospaced_();

        sink.text( " " );

        sink.italic();
        sink.text( delta );
        sink.italic_();
    }

    @Override
    protected void endDiff( final Object context, int depth )
    {
        final Context ctx = (Context)context;
        final Sink sink = ctx.sink;

        sink.listItem_();

        if ( ctx.currentDepth > depth )
        {
            sink.list_();
        }

        ctx.currentDepth = depth;
    }

    @Override
    protected void endPackage(final Object context)
    {
        final Context ctx = (Context)context;
        final Sink sink = ctx.sink;
        if ( ctx.currentDepth > 0 )
        {
            sink.list_();
            ctx.currentDepth = 0;
        }

        sink.listItem_();
        sink.list_();
    }

    @Override
    protected void endBaseline(final Object context)
    {
        final Context ctx = (Context)context;
        ctx.sink.body_();
        ctx.sink.flush();
        ctx.sink.close();
    }

    // MavenReport methods

    public boolean canGenerateReport()
    {
        return !skip && outputDirectory != null;
    }

    public void generate( @SuppressWarnings( "deprecation" ) org.codehaus.doxia.sink.Sink sink, Locale locale )
        throws MavenReportException
    {
        final Context ctx = new Context();
        ctx.sink = sink;
        ctx.locale = locale;

        try
        {
            execute(ctx);
        }
        catch ( Exception e )
        {
            getLog().warn( "An error occurred while producing the report page, see nested exceptions", e );
        }
    }

    public String getCategoryName()
    {
        return MavenReport.CATEGORY_PROJECT_REPORTS;
    }

    public String getDescription( Locale locale )
    {
        return getBundle( locale ).getString( "report.baseline.description" );
    }

    public String getName( Locale locale )
    {
        return getBundle( locale ).getString( "report.baseline.name" );
    }

    private ResourceBundle getBundle( Locale locale )
    {
        return ResourceBundle.getBundle( "baseline-report", locale, getClass().getClassLoader() );
    }

    public String getOutputName()
    {
        return "baseline-report";
    }

    public File getReportOutputDirectory()
    {
        return outputDirectory;
    }

    public boolean isExternalReport()
    {
        return false;
    }

    public void setReportOutputDirectory( File outputDirectory )
    {
        this.outputDirectory = outputDirectory;
    }

}
