/*
 * This code is free software; you can redistribute it and/or modify it under
 * the terms of the new BSD License.
 *
 * Copyright (c) 2011-2017, Sebastian Staudt
 */

package com.github.koraktor.mavanagaiata.mojo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.maven.plugins.annotations.Parameter;

import com.github.koraktor.mavanagaiata.git.GitRepository;

/**
 * This abstract Mojo implements writing output to a <code>PrintStream</code>
 *
 * This is either <code>System.out</code> by default, but maybe another
 * <code>PrintStream</code> object wrapped around a file given by
 * <code>outputFile</code>.
 *
 * @author Sebastian Staudt
 * @see File
 * @see PrintStream
 * @since 0.2.2
 */
abstract class AbstractGitOutputMojo extends AbstractGitMojo {

    /**
     * The encoding to use for generated output
     */
    @Parameter(property = "mavanagaiata.encoding",
               defaultValue = "UTF-8")
    protected String encoding;

    /**
     * The footer to print below the output
     */
    @Parameter(property = "mavanagaiata.footer",
               defaultValue = "\nGenerated by Mavanagaiata at %s")
    protected String footer;

    /**
     * Unescapes newlines for format strings
     *
     * @param format The escaped format string
     * @return The unescaped format string
     */
    static String unescapeFormatNewlines(String format) {
        return format.replaceAll("([^\\\\]?)\\\\n", "$1\n");
    }

    protected void initConfiguration() {
        footer = unescapeFormatNewlines(footer);
    }

    /**
     * Initializes the output stream for the generated content
     *
     * @throws MavanagaiataMojoException if the output file can not be opened
     */
    @Override
    protected GitRepository init() throws MavanagaiataMojoException {
        this.initConfiguration();

        return super.init();
    }

    /**
     * Returns the output file for the generated content
     * <p>
     * Has to be implemented by subclassing mojos, so that the output file
     * can be easily configured.
     *
     * @return The output file for the generated content
     */
    public abstract File getOutputFile();

    /**
     * Initializes the <code>PrintStream</code> to use
     *
     * This is <code>System.out</code> if no output file is given (default).
     * Otherwise the parent directories of <code>outputFile</code> are created
     * and a new <code>PrintStream</code> for that file is created.
     *
     * @throws MavanagaiataMojoException if the file specified by
     *         <code>outputFile</code> cannot be opened for writing or the
     *         target directory cannot be created
     */
    @Override
    protected final void run(GitRepository repository) throws MavanagaiataMojoException {
        if (getOutputFile() == null) {
            generateOutput(repository, System.out);
        } else {
            File parentDirectory = getOutputFile().getParentFile();
            if (parentDirectory.isFile() ||
                    (!parentDirectory.exists() && !parentDirectory.mkdirs())) {
                throw MavanagaiataMojoException.create("Could not create directory \"%s\" for output file.",
                        null,
                        parentDirectory.getAbsolutePath());
            }

            try (PrintStream printStream = createPrintStream()) {
                generateOutput(repository, printStream);
            } catch (FileNotFoundException | UnsupportedEncodingException e) {
                throw MavanagaiataMojoException.create(
                                        "Could not open output file \"%s\" for writing.",
                                        e,
                                        getOutputFile().getAbsolutePath());
            }
        }
    }

    /**
     * Creates a new print stream for the configured outputfile and encoding
     *
     * @return A new print stream
     */
    PrintStream createPrintStream()
            throws FileNotFoundException, UnsupportedEncodingException {
        return new PrintStream(getOutputFile(), encoding);
    }

    /**
     * Sets the output file for the generated content
     *
     * @param outputFile The output file for the generated content
     */
    public abstract void setOutputFile(File outputFile);

    /**
     * This must be implemented by mojos for writing their output
     *
     * @param repository The repository the mojo is running in
     * @param printStream The stream the output should be printed to
     * @throws MavanagaiataMojoException if the output cannot be generated
     */
    protected abstract void writeOutput(GitRepository repository, PrintStream printStream)
            throws MavanagaiataMojoException;

    /**
     * Writes the (optional) footer and flushes the {@code PrintStream} after
     * calling the main mojo implementation
     *
     * @see #writeOutput
     * @throws MavanagaiataMojoException if the output cannot be generated
     */
    protected void generateOutput(GitRepository repository, PrintStream printStream)
            throws MavanagaiataMojoException {
        writeOutput(repository, printStream);

        if (footer.length() > 0) {
            SimpleDateFormat baseDateFormat = new SimpleDateFormat(dateFormat);
            printStream.println(String.format(footer,
                    VersionHelper.getVersion(),
                    baseDateFormat.format(new Date())));
        }

        printStream.flush();
    }

}

@@ -1272,16 +1272,19 @@
 agaiata 
+%25s 
 at %25s%22)%0A

Fix output footer