package org.apache.maven.plugins.site.descriptor;

/*
 * 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 org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.maven.doxia.site.decoration.DecorationModel;
import org.apache.maven.doxia.site.decoration.io.xpp3.DecorationXpp3Writer;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.WriterFactory;
import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
import org.codehaus.plexus.util.xml.XMLWriter;
import org.codehaus.plexus.util.xml.XmlWriterUtil;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;

/**
 * Displays the effective site descriptor as an XML for this build, after inheritance and interpolation of
 * <code>site.xml</code>, for the first locale.
 *
 * @author <a href="mailto:hboutemy@apache.org">Hervé Boutemy</a>
 *
 * @since 2.2
 */
@Mojo( name = "effective-site", requiresReports = true )
public class EffectiveSiteMojo
    extends AbstractSiteDescriptorMojo
{
    /**
     * Optional parameter to write the output of this help in a given file, instead of writing to the console.
     * <br/>
     * <b>Note</b>: Could be a relative path.
     */
    @Parameter( property = "output" )
    protected File output;

    /**
     * {@inheritDoc}
     */
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        DecorationModel decorationModel = prepareDecorationModel( getLocales().get( 0 ) );

        StringWriter w = new StringWriter();
        XMLWriter writer =
            new PrettyPrintXMLWriter( w, StringUtils.repeat( " ", XmlWriterUtil.DEFAULT_INDENTATION_SIZE ),
                                      decorationModel.getModelEncoding(), null );

        writeHeader( writer );

        writeEffectiveSite( decorationModel, writer );

        String effectiveSite = w.toString();

        if ( output != null )
        {
            try
            {
                writeXmlFile( output, effectiveSite );
            }
            catch ( IOException e )
            {
                throw new MojoExecutionException( "Cannot write effective site descriptor to output: " + output, e );
            }

            if ( getLog().isInfoEnabled() )
            {
                getLog().info( "Effective site descriptor written to: " + output );
            }
        }
        else
        {
            StringBuilder message = new StringBuilder();

            message.append( "\nEffective site descriptor, after inheritance and interpolation:\n\n" );
            message.append( effectiveSite );
            message.append( "\n" );

            if ( getLog().isInfoEnabled() )
            {
                getLog().info( message.toString() );
            }
        }
    }

    /**
     * Write comments in the Effective POM/settings header.
     *
     * @param writer not null
     */
    protected static void writeHeader( XMLWriter writer )
    {
        XmlWriterUtil.writeCommentLineBreak( writer );
        XmlWriterUtil.writeComment( writer, " " );
        // Use ISO 8601 format for date and time
        String formattedDateTime = DateFormatUtils.ISO_DATETIME_FORMAT.format( System.currentTimeMillis() );
        XmlWriterUtil.writeComment( writer, "Generated by Maven Site Plugin on " + formattedDateTime );
        XmlWriterUtil.writeComment( writer, "See: http://maven.apache.org/plugins/maven-site-plugin/" );
        XmlWriterUtil.writeComment( writer, " " );
        XmlWriterUtil.writeCommentLineBreak( writer );

        XmlWriterUtil.writeLineBreak( writer );
    }

    /**
     * Write comments in a normalize way.
     *
     * @param writer not null
     * @param comment not null
     */
    protected static void writeComment( XMLWriter writer, String comment )
    {
        XmlWriterUtil.writeCommentLineBreak( writer );
        XmlWriterUtil.writeComment( writer, " " );
        XmlWriterUtil.writeComment( writer, comment );
        XmlWriterUtil.writeComment( writer, " " );
        XmlWriterUtil.writeCommentLineBreak( writer );

        XmlWriterUtil.writeLineBreak( writer );
    }

    private void writeEffectiveSite( DecorationModel decorationModel, XMLWriter writer )
        throws MojoExecutionException
    {
        String effectiveSite;

        StringWriter sWriter = new StringWriter();
        DecorationXpp3Writer siteWriter = new DecorationXpp3Writer();
        try
        {
            siteWriter.write( sWriter, decorationModel );
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Cannot serialize site descriptor to XML.", e );
        }

        effectiveSite = sWriter.toString();
        effectiveSite = effectiveSite.substring( effectiveSite.indexOf( "<project " ) ); // remove "<?xml" header

        writeComment( writer, "Effective site descriptor for project \'" + project.getId() + "\'" );

        writer.writeMarkup( effectiveSite );
    }

    protected static void writeXmlFile( File output, String content )
        throws IOException
    {
        try ( Writer out = WriterFactory.newXmlWriter( output ) )
        {
            output.getParentFile().mkdirs();

            out.write( content );
        }
    }
}
