/*
 *  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.tools.ant.taskdefs.optional;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.taskdefs.LogOutputStream;
import org.apache.tools.ant.taskdefs.PumpStreamHandler;
import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.CommandlineJava;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.JavaEnvUtils;
import org.apache.tools.ant.util.LoaderUtils;
import org.apache.tools.ant.util.TeeOutputStream;

/**
 *  Invokes the ANTLR Translator generator on a grammar file.
 *
 */
public class ANTLR extends Task {

    private CommandlineJava commandline = new CommandlineJava();

    /** the file to process */
    private File targetFile;

    /** where to output the result */
    private File outputDirectory;

    /** an optional super grammar file */
    private File superGrammar;

    /** optional flag to enable html output */
    private boolean html;

    /** optional flag to print out a diagnostic file */
    private boolean diagnostic;

    /** optional flag to add trace methods */
    private boolean trace;

    /** optional flag to add trace methods to the parser only */
    private boolean traceParser;

    /** optional flag to add trace methods to the lexer only */
    private boolean traceLexer;

    /** optional flag to add trace methods to the tree walker only */
    private boolean traceTreeWalker;

    /** working directory */
    private File workingdir = null;

    /** captures ANTLR's output */
    private ByteArrayOutputStream bos = new ByteArrayOutputStream();

    /** The debug attribute */
    private boolean debug;


    /** Instance of a utility class to use for file operations. */
    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

    /** Constructor for ANTLR task. */
    public ANTLR() {
        commandline.setVm(JavaEnvUtils.getJreExecutable("java"));
        commandline.setClassname("antlr.Tool");
    }

    /**
     * The grammar file to process.
     * @param target the grammar file
     */
    public void setTarget(File target) {
        log("Setting target to: " + target.toString(), Project.MSG_VERBOSE);
        this.targetFile = target;
    }

    /**
     * The directory to write the generated files to.
     * @param outputDirectory the output directory
     */
    public void setOutputdirectory(File outputDirectory) {
        log("Setting output directory to: " + outputDirectory.toString(), Project.MSG_VERBOSE);
        this.outputDirectory = outputDirectory;
    }

    /**
     * Sets an optional super grammar file.
     * Use setGlib(File superGrammar) instead.
     * @param superGrammar the super grammar filename
     * @deprecated  since ant 1.6
     */
    public void setGlib(String superGrammar) {
        String sg = null;
        if (Os.isFamily("dos")) {
            sg = superGrammar.replace('\\', '/');
        } else {
            sg = superGrammar;
        }
        setGlib(FILE_UTILS.resolveFile(getProject().getBaseDir(), sg));
    }
    /**
     * Sets an optional super grammar file
     * @param superGrammar the super grammar file
     * @since ant 1.6
     */
    public void setGlib(File superGrammar) {
        this.superGrammar = superGrammar;
    }
    /**
     * Sets a flag to enable ParseView debugging
     * @param enable a <code>boolean</code> value
     */
    public void setDebug(boolean enable) {
        this.debug = enable;
    }

    /**
     * If true, emit html
     * @param enable a <code>boolean</code> value
     */
    public void setHtml(boolean enable) {
        html = enable;
    }

    /**
     * Sets a flag to emit diagnostic text
     * @param enable a <code>boolean</code> value
     */
    public void setDiagnostic(boolean enable) {
        diagnostic = enable;
    }

    /**
     * If true, enables all tracing.
     * @param enable a <code>boolean</code> value
     */
    public void setTrace(boolean enable) {
        trace = enable;
    }

    /**
     * If true, enables parser tracing.
     * @param enable a <code>boolean</code> value
     */
    public void setTraceParser(boolean enable) {
        traceParser = enable;
    }

    /**
     * If true, enables lexer tracing.
     * @param enable a <code>boolean</code> value
     */
    public void setTraceLexer(boolean enable) {
        traceLexer = enable;
    }

    /**
     * Sets a flag to allow the user to enable tree walker tracing
     * @param enable a <code>boolean</code> value
     */
    public void setTraceTreeWalker(boolean enable) {
        traceTreeWalker = enable;
    }

    // we are forced to fork ANTLR since there is a call
    // to System.exit() and there is nothing we can do
    // right now to avoid this. :-( (SBa)
    // I'm not removing this method to keep backward compatibility
    /**
     * @ant.attribute ignore="true"
     * @param s a <code>boolean</code> value
     */
    public void setFork(boolean s) {
        //this.fork = s;
    }

    /**
     * The working directory of the process
     * @param d the working directory
     */
    public void setDir(File d) {
        this.workingdir = d;
    }

    /**
     * Adds a classpath to be set
     * because a directory might be given for Antlr debug.
     * @return a path to be configured
     */
    public Path createClasspath() {
        return commandline.createClasspath(getProject()).createPath();
    }

    /**
     * Adds a new JVM argument.
     * @return  create a new JVM argument so that any argument can be passed to the JVM.
     * @see #setFork(boolean)
     */
    public Commandline.Argument createJvmarg() {
        return commandline.createVmArgument();
    }

    /**
     * Adds the jars or directories containing Antlr
     * this should make the forked JVM work without having to
     * specify it directly.
     * @throws BuildException on error
     */
    public void init() throws BuildException {
        addClasspathEntry("/antlr/ANTLRGrammarParseBehavior.class");
    }

    /**
     * Search for the given resource and add the directory or archive
     * that contains it to the classpath.
     *
     * <p>Doesn't work for archives in JDK 1.1 as the URL returned by
     * getResource doesn't contain the name of the archive.</p>
     * @param resource the resource name to search for
     */
    protected void addClasspathEntry(String resource) {
        /*
         * pre Ant 1.6 this method used to call getClass().getResource
         * while Ant 1.6 will call ClassLoader.getResource().
         *
         * The difference is that Class.getResource expects a leading
         * slash for "absolute" resources and will strip it before
         * delegating to ClassLoader.getResource - so we now have to
         * emulate Class's behavior.
         */
        if (resource.startsWith("/")) {
            resource = resource.substring(1);
        } else {
            resource = "org/apache/tools/ant/taskdefs/optional/"
                + resource;
        }

        File f = LoaderUtils.getResourceSource(getClass().getClassLoader(),
                                               resource);
        if (f != null) {
            log("Found " + f.getAbsolutePath(), Project.MSG_DEBUG);
            createClasspath().setLocation(f);
        } else {
            log("Couldn\'t find " + resource, Project.MSG_VERBOSE);
        }
    }

    /**
     * Execute the task.
     * @throws BuildException on error
     */
    public void execute() throws BuildException {
        validateAttributes();

        //TODO: use ANTLR to parse the grammar file to do this.
        File generatedFile = getGeneratedFile();
        boolean targetIsOutOfDate =
            targetFile.lastModified() > generatedFile.lastModified();
        boolean superGrammarIsOutOfDate  = superGrammar != null
                && (superGrammar.lastModified() > generatedFile.lastModified());
        if (targetIsOutOfDate || superGrammarIsOutOfDate) {
            if (targetIsOutOfDate) {
                log("Compiling " + targetFile + " as it is newer than "
                    + generatedFile, Project.MSG_VERBOSE);
            } else {
                log("Compiling " + targetFile + " as " + superGrammar
                    + " is newer than " + generatedFile, Project.MSG_VERBOSE);
            }
            populateAttributes();
            commandline.createArgument().setValue(targetFile.toString());

            log(commandline.describeCommand(), Project.MSG_VERBOSE);
            int err = run(commandline.getCommandline());
            if (err != 0) {
                throw new BuildException("ANTLR returned: " + err, getLocation());
            }
            String output = bos.toString();
            if (output.contains("error:")) {
                throw new BuildException("ANTLR signaled an error: "
                                         + output, getLocation());
            }
        } else {
            log("Skipped grammar file. Generated file " + generatedFile
                + " is newer.", Project.MSG_VERBOSE);
        }
    }

    /**
     * A refactored method for populating all the command line arguments based
     * on the user-specified attributes.
     */
    private void populateAttributes() {
        commandline.createArgument().setValue("-o");
        commandline.createArgument().setValue(outputDirectory.toString());
        if (superGrammar != null) {
            commandline.createArgument().setValue("-glib");
            commandline.createArgument().setValue(superGrammar.toString());
        }
        if (html) {
            commandline.createArgument().setValue("-html");
        }
        if (diagnostic) {
            commandline.createArgument().setValue("-diagnostic");
        }
        if (trace) {
            commandline.createArgument().setValue("-trace");
        }
        if (traceParser) {
            commandline.createArgument().setValue("-traceParser");
        }
        if (traceLexer) {
            commandline.createArgument().setValue("-traceLexer");
        }
        if (traceTreeWalker) {
            if (is272()) {
                commandline.createArgument().setValue("-traceTreeParser");
            } else {
                commandline.createArgument().setValue("-traceTreeWalker");
            }
        }
        if (debug) {
            commandline.createArgument().setValue("-debug");
        }
    }

    private void validateAttributes() throws BuildException {
        if (targetFile == null || !targetFile.isFile()) {
            throw new BuildException("Invalid target: " + targetFile);
        }

        // if no output directory is specified, used the target's directory
        if (outputDirectory == null) {
            setOutputdirectory(new File(targetFile.getParent()));
        }
        if (!outputDirectory.isDirectory()) {
            throw new BuildException("Invalid output directory: " + outputDirectory);
        }
    }

    private File getGeneratedFile() throws BuildException {
        String generatedFileName = null;
        try {
            BufferedReader in = new BufferedReader(new FileReader(targetFile));
            String line;
            while ((line = in.readLine()) != null) {
                int extendsIndex = line.indexOf(" extends ");
                if (line.startsWith("class ") && extendsIndex > -1) {
                    generatedFileName = line.substring(
                        "class ".length(), extendsIndex).trim();
                    break;
                }
            }
            in.close();
        } catch (Exception e) {
            throw new BuildException("Unable to determine generated class", e);
        }
        if (generatedFileName == null) {
            throw new BuildException("Unable to determine generated class");
        }
        return new File(outputDirectory, generatedFileName
                        + (html ? ".html" : ".java"));
    }

    /** execute in a forked VM */
    private int run(String[] command) throws BuildException {
        PumpStreamHandler psh =
            new PumpStreamHandler(new LogOutputStream(this, Project.MSG_INFO),
                                  new TeeOutputStream(
                                                      new LogOutputStream(this,
                                                                          Project.MSG_WARN),
                                                      bos)
                                  );
        Execute exe = new Execute(psh, null);
        exe.setAntRun(getProject());
        if (workingdir != null) {
            exe.setWorkingDirectory(workingdir);
        }
        exe.setCommandline(command);
        try {
            return exe.execute();
        } catch (IOException e) {
            throw new BuildException(e, getLocation());
        } finally {
            FileUtils.close(bos);
        }
    }

    /**
     * Whether the antlr version is 2.7.2 (or higher).
     *
     * @return true if the version of Antlr present is 2.7.2 or later.
     * @since Ant 1.6
     */
    protected boolean is272() {
        AntClassLoader l = null;
        try {
            l = getProject().createClassLoader(commandline.getClasspath());
            l.loadClass("antlr.Version");
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        } finally {
            if (l != null) {
                l.cleanup();
            }
        }
    }
}
