/**
[The "BSD licence"]

ANTLR        - Copyright (c) 2005-2008 Terence Parr
Maven Plugin - Copyright (c) 2009      Jim Idle

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* ========================================================================
 * This is the definitive ANTLR3 Mojo set. All other sets are belong to us.
 */
package org.antlr.mojo.antlr3;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.antlr.Tool;
import org.antlr.runtime.RecognitionException;
import org.apache.maven.plugin.logging.Log;
import org.codehaus.plexus.compiler.util.scan.InclusionScanException;
import org.codehaus.plexus.compiler.util.scan.SimpleSourceInclusionScanner;
import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner;
import org.codehaus.plexus.compiler.util.scan.mapping.SourceMapping;
import org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping;

/**
 * Goal that picks up all the ANTLR grammars in a project and moves those that
 * are required for generation of the compilable sources into the location
 * that we use to compile them, such as target/generated-sources/antlr3 ...
 *
 * @goal antlr
 * 
 * @phase process-sources
 * @requiresDependencyResolution compile
 * @requiresProject true
 * 
 * @author <a href="mailto:jimi@temporal-wave.com">Jim Idle</a>
 */
public class Antlr3Mojo
        extends AbstractMojo {

    // First, let's deal with the options that the ANTLR tool itself
    // can be configured by.
    //
    /**
     * If set to true, then after the tool has processed an input grammar file
     * it will report various statistics about the parser, such as information
     * on cyclic DFAs, which rules may use backtracking, and so on.
     *
     * @parameter default-value="false"
     */
    protected boolean report;
    /**
     * If set to true, then the ANTLR tool will print a version of the input
     * grammar which is devoid of any actions that may be present in the input file.
     *
     * @parameter default-value="false"
     */
    protected boolean printGrammar;
    /**
     * If set to true, then the code generated by the ANTLR code generator will
     * be set to debug mode. This means that when run, the code will 'hang' and
     * wait for a debug connection on a TCP port (49100 by default).
     *
     * @parameter default-value="false"
     */
    protected boolean debug;
    /**
     * If set to true, then then the generated parser will compute and report on
     * profile information at runtime.
     *
     * @parameter default-value="false"
     */
    protected boolean profile;
    /**
     * If set to true then the ANTLR tool will generate a description of the nfa
     * for each rule in <a href="http://www.graphviz.org">Dot format</a>
     * 
     * @parameter default-value="false"
     */
    protected boolean nfa;
    /**
     * If set to true then the ANTLR tool will generate a description of the DFA
     * for each decision in the grammar in <a href="http://www.graphviz.org">Dot format</a>
     * 
     * @parameter default-value="false"
     */
    protected boolean dfa;
    /**
     * If set to true, the generated parser code will log rule entry and exit points
     * to stdout as an aid to debugging.
     *
     * @parameter default-value="false"
     */
    protected boolean trace;
    /**
     * If this parameter is set, it indicates that any warning or error messages returned
     * by ANLTR, should be formatted in the specified way. Currently, ANTLR supports the
     * built-in formats of antlr, gnu and vs2005.
     *
     * @parameter default-value="antlr"
     */
    protected String messageFormat;
    /**
     * If this parameter is set to true, then ANTLR will report all sorts of things
     * about what it is doing such as the names of files and the version of ANTLR and so on.
     *
     * @parameter default-value="true"
     */
    protected boolean verbose;

    /**
     * The number of alts, beyond which ANTLR will not generate a switch statement
     * for the DFA.
     *
     * @parameter default-value="300"
     */
    private int maxSwitchCaseLabels;

    /**
     * The number of alts, below which ANTLR will not choose to generate a switch
     * statement over an if statement.
     */
    private int minSwitchAlts;

    /* --------------------------------------------------------------------
     * The following are Maven specific parameters, rather than specificlly
     * options that the ANTLR tool can use.
     */
    /**
     * Provides an explicit list of all the grammars that should
     * be included in the generate phase of the plugin. Note that the plugin
     * is smart enough to realize that imported grammars should be included but
     * not acted upon directly by the ANTLR Tool.
     *
     * Unless otherwise specified, the include list scans for and includes all
     * files that end in ".g" in any directory beneath src/main/antlr3. Note that
     * this version of the plugin looks for the directory antlr3 and not the directory
     * antlr, so as to avoid clashes and confusion for projects that use both v2 and v3 grammars
     * such as ANTLR itself.
     *
     * @parameter
     */
    protected Set includes = new HashSet();
    /**
     * Provides an explicit list of any grammars that should be excluded from
     * the generate phase of the plugin. Files listed here will not be sent for
     * processing by the ANTLR tool.
     *
     * @parameter 
     */
    protected Set excludes = new HashSet();
    /**
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    protected MavenProject project;
    /**
     * Specifies the Antlr directory containing grammar files. For
     * antlr version 3.x we default this to a directory in the tree
     * called antlr3 because the antlr directory is occupied by version
     * 2.x grammars.
     *
     * @parameter default-value="${basedir}/src/main/antlr3"
     * @required
     */
    private File sourceDirectory;
    /**
     * Location for generated Java files. For antlr version 3.x we default
     * this to a directory in the tree called antlr3 because the antlr
     * directory is occupied by version 2.x grammars.
     *
     * @parameter default-value="${project.build.directory}/generated-sources/antlr3"
     * @required
     */
    private File outputDirectory;
    /**
     * Location for imported token files, e.g. <code>.tokens</code> and imported grammars.
     * Note that ANTLR will not try to process grammars that it finds to be imported
     * into other grammars (in the same processing session).
     *
     * @parameter default-value="${basedir}/src/main/antlr3/imports"
     */
    private File libDirectory;

    public File getSourceDirectory() {
        return sourceDirectory;
    }

    public File getOutputDirectory() {
        return outputDirectory;
    }

    public File getLibDirectory() {
        return libDirectory;
    }

    void addSourceRoot(File outputDir) {
        project.addCompileSourceRoot(outputDir.getPath());
    }
    /**
     * An instance of the ANTLR tool build
     */
    protected Tool tool;

    /**
     * The main entry point for this Mojo, it is responsible for converting
     * ANTLR 3.x grammars into the target language specified by the grammar.
     * 
     * @throws org.apache.maven.plugin.MojoExecutionException When something is discovered such as a missing source
     * @throws org.apache.maven.plugin.MojoFailureException When something really bad happens such as not being able to create the ANTLR Tool
     */
    public void execute()
            throws MojoExecutionException, MojoFailureException {

        Log log = getLog();

        // Check to see if the user asked for debug information, then dump all the
        // parameters we have picked up if they did.
        //
        if (log.isDebugEnabled()) {

            // Excludes
            //
            for (String e : (Set<String>) excludes) {

                log.debug("ANTLR: Exclude: " + e);
            }

            // Includes
            //
            for (String e : (Set<String>) includes) {

                log.debug("ANTLR: Include: " + e);
            }

            // Output location
            //
            log.debug("ANTLR: Output: " + outputDirectory);

            // Library directory
            //
            log.debug("ANTLR: Library: " + libDirectory);

            // Flags
            //
            log.debug("ANTLR: report              : " + report);
            log.debug("ANTLR: printGrammar        : " + printGrammar);
            log.debug("ANTLR: debug               : " + debug);
            log.debug("ANTLR: profile             : " + profile);
            log.debug("ANTLR: nfa                 : " + nfa);
            log.debug("ANTLR: dfa                 : " + dfa);
            log.debug("ANTLR: trace               : " + trace);
            log.debug("ANTLR: messageFormat       : " + messageFormat);
            log.debug("ANTLR: maxSwitchCaseLabels : " + maxSwitchCaseLabels);
            log.debug("ANTLR: minSwitchAlts       : " + minSwitchAlts);
            log.debug("ANTLR: verbose             : " + verbose);
        }

        // Ensure that the output directory path is all in tact so that
        // ANTLR can just write into it.
        //
        File outputDir = getOutputDirectory();

        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }

        // First thing we need is an instance of the ANTLR 3.1 build tool
        //
        try {
            // ANTLR Tool buld interface
            //
            tool = new Tool();
        } catch (Exception e) {
            log.error("The attempt to create the ANTLR build tool failed, see exception report for details");

            throw new MojoFailureException("Jim failed you!");
        }

        // Next we need to set the options given to us in the pom into the
        // tool instance we have created.
        //
        tool.setDebug(debug);
        tool.setGenerate_DFA_dot(dfa);
        tool.setGenerate_NFA_dot(nfa);
        tool.setProfile(profile);
        tool.setReport(report);
        tool.setPrintGrammar(printGrammar);
        tool.setTrace(trace);
        tool.setVerbose(verbose);
        tool.setMessageFormat(messageFormat);
        tool.setMaxSwitchCaseLabels(maxSwitchCaseLabels);
        tool.setMinSwitchAlts(minSwitchAlts);

        // Where do we want ANTLR to produce its output? (Base directory)
        //
        if (log.isDebugEnabled())
        {
            log.debug("Output directory base will be " + outputDirectory.getAbsolutePath());
        }
        tool.setOutputDirectory(outputDirectory.getAbsolutePath());

        // Tell ANTLR that we always want the output files to be produced in the output directory
        // using the same relative path as the input file was to the input directory.
        //
        tool.setForceRelativeOutput(true);

        // Where do we want ANTLR to look for .tokens and import grammars?
        //
        tool.setLibDirectory(libDirectory.getAbsolutePath());

        if (!sourceDirectory.exists()) {
            if (log.isInfoEnabled()) {
                log.info("No ANTLR grammars to compile in " + sourceDirectory.getAbsolutePath());
            }
            return;
        } else {
            if (log.isInfoEnabled()) {
                log.info("ANTLR: Processing source directory " + sourceDirectory.getAbsolutePath());
            }
        }

        // Set working directory for ANTLR to be the base source directory
        //
        tool.setInputDirectory(sourceDirectory.getAbsolutePath());

        try {

            // Now pick up all the files and process them with the Tool
            //
            processGrammarFiles(sourceDirectory, outputDirectory);

        } catch (InclusionScanException ie) {

            log.error(ie);
            throw new MojoExecutionException("Fatal error occured while evaluating the names of the grammar files to analyze");

        } catch (Exception e) {

            getLog().error(e);
            throw new MojoExecutionException(e.getMessage());
        }



        tool.process();

        // If any of the grammar files caused errors but did nto throw exceptions
        // then we should have accumulated errors in the counts
        //
        if (tool.getNumErrors() > 0) {
            throw new MojoExecutionException("ANTLR caught " + tool.getNumErrors() + " build errors.");
        }

        // All looks good, so we need to tel Maven about the sources that
        // we just created.
        //
        if (project != null) {
            // Tell Maven that there are some new source files underneath
            // the output directory.
            //
            addSourceRoot(this.getOutputDirectory());
        }

    }


    /**
     *
     * @param sourceDirectory
     * @param outputDirectory
     * @throws antlr.TokenStreamException
     * @throws antlr.RecognitionException
     * @throws java.io.IOException
     * @throws org.codehaus.plexus.compiler.util.scan.InclusionScanException
     */
    private void processGrammarFiles(File sourceDirectory, File outputDirectory)
            throws RecognitionException, IOException, InclusionScanException {
        // Which files under the source set should we be looking for as grammar files
        //
        SourceMapping mapping = new SuffixMapping("g", Collections.EMPTY_SET);

        // What are the sets of includes (defaulted or otherwise).
        //
        Set includes = getIncludesPatterns();

        // Now, to the excludes, we need to add the imports directory
        // as this is autoscanned for importd grammars and so is auto-excluded from the
        // set of gramamr fiels we shuold be analyzing.
        //
        excludes.add("imports/**");

        SourceInclusionScanner scan = new SimpleSourceInclusionScanner(includes, excludes);

        scan.addSourceMapping(mapping);
        Set grammarFiles = scan.getIncludedSources(sourceDirectory, null);

        if (grammarFiles.isEmpty()) {
            if (getLog().isInfoEnabled()) {
                getLog().info("No grammars to process");
            }
        } else {

            // Tell the ANTLR tool that we want sorted build mode
            //
            tool.setMake(true);
            
            // Iterate each grammar file we were given and add it into the tool's list of
            // grammars to process.
            //
            for (File grammar : (Set<File>) grammarFiles) {

                if (getLog().isDebugEnabled()) {
                    getLog().debug("Grammar file '" + grammar.getPath() + "' detected.");
                }


                String relPath = findSourceSubdir(sourceDirectory, grammar.getPath()) + grammar.getName();

                if (getLog().isDebugEnabled()) {
                    getLog().debug("  ... relative path is: " + relPath);
                }
                tool.addGrammarFile(relPath);

            }

        }


    }

    public Set getIncludesPatterns() {
        if (includes == null || includes.isEmpty()) {
            return Collections.singleton("**/*.g");
        }
        return includes;
    }

    /**
     * Given the source directory File object and the full PATH to a
     * grammar, produce the path to the named grammar file in relative
     * terms to the sourceDirectory. This will then allow ANTLR to
     * produce output relative to the base of the output directory and
     * reflect the input organization of the grammar files.
     *
     * @param sourceDirectory The source directory File object
     * @param grammarFileName The full path to the input grammar file
     * @return The path to the grammar file relative to the source directory
     */
    private String findSourceSubdir(File sourceDirectory, String grammarFileName) {
        String srcPath = sourceDirectory.getPath() + File.separator;

        if (!grammarFileName.startsWith(srcPath)) {
            throw new IllegalArgumentException("expected " + grammarFileName + " to be prefixed with " + sourceDirectory);
        }

        File unprefixedGrammarFileName = new File(grammarFileName.substring(srcPath.length()));

        return unprefixedGrammarFileName.getParent() + File.separator;
    }
}
