package de.renew.ant;

import java.io.File;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Replace;
import org.apache.tools.ant.taskdefs.Replace.NestedString;
import org.apache.tools.ant.taskdefs.optional.javacc.JavaCC;


/**
 * Enhances the <code>JavaCC</code> task delivered with Ant to
 * work on a file set. The generated Java source of all processed
 * grammars can be put in a destination directory tree similar to
 * the one where the grammar files are kept.
 *
 * @author "Timo Carl" <a href="6carl@informatik.uni-hamburg.de">6carl@informatik.uni-hamburg.de</a>
 *
 * @see org.apache.tools.ant.taskdefs.optional.javacc.JavaCC
 **/
public class EnhancedJavaCCTask extends AbstractEnhancedJavaCCTask {
    private String _jdkversion;

    /**
     * Sets the used JDKversion.
     * @param jdkversion the current JDKversion.
     */
    public void setJDKversion(String jdkversion) {
        this._jdkversion = jdkversion;
    }

    /**
     * Constructor of the class, just calls the constructor of the superclass with the argument "javacc".
     */
    public EnhancedJavaCCTask() {
        super("javacc");
    }

    @Override
    protected void mkdirAndExecuteJavaCC(File javaccFile) throws BuildException {
        super.mkdirAndExecuteJavaCC(javaccFile);
        suppressWarningsInTokenManager(javaccFile, getGenerationDirectory(javaccFile));
    }

    @Override
    protected void executeJavaCC(File javaccFile, File directory) throws BuildException {
        JavaCC task = (JavaCC) getProject().createTask(_singleTaskName);
        task.setJavacchome(_javacchome);
        task.setTarget(javaccFile);
        task.setOutputdirectory(directory);
        if (_jdkversion != null) {
            task.setJDKversion(_jdkversion);
        }
        task.init();
        task.execute();
    }

    private void suppressWarningsInTokenManager(File javaccFile, File directory) {
        String javaccfilename = javaccFile.getName();
        if (javaccfilename == null || !javaccfilename.endsWith(".jj")) {
            log(
                "Cannot determine filename of token manager to add @SuppressWarnings. "
                    + "Skipping this step.",
                Project.MSG_WARN);
        } else {
            String tokenmanagerfilename =
                javaccfilename.substring(0, javaccfilename.length() - 3) + "TokenManager.java";
            File tokenmanagerfile = new File(directory, tokenmanagerfilename);
            log(
                "Trying to insert @SuppressWarnings(\"unused\") in " + tokenmanagerfile,
                Project.MSG_VERBOSE);
            Replace rtask = (Replace) getProject().createTask("replace");
            rtask.setFile(tokenmanagerfile);
            NestedString search = rtask.createReplaceToken();
            search.addText("/** Token Manager. */\npublic class");
            NestedString replace = rtask.createReplaceValue();
            replace.addText("/** Token Manager. */\n@SuppressWarnings(\"unused\")\npublic class");
            rtask.execute();
        }
    }
}