/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2002 The Apache Software Foundation.  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 end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS 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 software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.tools.ant.taskdefs.optional.jdepend;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;


import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.PathTokenizer;
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.ExecuteWatchdog;
import org.apache.tools.ant.taskdefs.LogStreamHandler;
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.types.Reference;
import org.apache.tools.ant.types.EnumeratedAttribute;

/**
 * Runs JDepend tests.
 *
 * <p>JDepend is a tool to generate design quality metrics for each Java package.
 * It has been initially created by Mike Clark. JDepend can be found at <a
 * href="http://www.clarkware.com/software/JDepend.html">http://www.clarkware.com/software/JDepend.html</a>.
 *
 * The current implementation spawn a new Java VM.
 *
 * @author <a href="mailto:Jerome@jeromelacoste.com">Jerome Lacoste</a>
 * @author <a href="mailto:roxspring@yahoo.com">Rob Oxspring</a>
 */
public class JDependTask extends Task {
    //private CommandlineJava commandline = new CommandlineJava();

    // required attributes
    private Path _sourcesPath;

    // optional attributes
    private File _outputFile;
    private File _dir;
    private Path _compileClasspath;
    private boolean _haltonerror = false;
    private boolean _fork = false;
    //private Integer _timeout = null;

    private String _jvm = null;
    private String format = "text";

    public JDependTask() {

    }

/*
    public void setTimeout(Integer value) {
        _timeout = value;
    }

    public Integer getTimeout() {
        return _timeout;
    }
*/

    /**
     * The output file name.
     *
     * @param outputFile
     */
    public void setOutputFile(File outputFile) {
        _outputFile = outputFile;
    }

    public File getOutputFile() {
        return _outputFile;
    }

    /**
     * Whether or not to halt on failure. Default: false.
     */
    public void setHaltonerror(boolean value) {
        _haltonerror = value;
    }

    public boolean getHaltonerror() {
        return _haltonerror;
    }

    /**
     * If true, forks into a new JVM. Default: false.
     *
     * @param   value   <tt>true</tt> if a JVM should be forked, otherwise <tt>false<tt>
     */
    public void setFork(boolean value) {
        _fork = value;
    }

    public boolean getFork() {
        return _fork;
    }

    /**
     * The command used to invoke a forked Java Virtual Machine.
     *
     * Default is <tt>java</tt>. Ignored if no JVM is forked.
     * @param   value   the new VM to use instead of <tt>java</tt>
     * @see #setFork(boolean)
     */
    public void setJvm(String value) {
        _jvm = value;

    }

    /**
     * Adds a path to source code to analyze.
     */
    public Path createSourcespath() {
        if (_sourcesPath == null) {
            _sourcesPath = new Path(project);
        }
        return _sourcesPath.createPath();
    }

    /** Gets the sourcepath. */
    public Path getSourcespath() {
        return _sourcesPath;
    }

    /**
     * The directory to invoke the VM in. Ignored if no JVM is forked.
     * @param   dir     the directory to invoke the JVM from.
     * @see #setFork(boolean)
     */
    public void setDir(File dir) {
        _dir = dir;
    }

    public File getDir() {
        return _dir;
    }

    /**
     * Set the classpath to be used for this compilation.
     */
    public void setClasspath(Path classpath) {
        if (_compileClasspath == null) {
            _compileClasspath = classpath;
        } else {
            _compileClasspath.append(classpath);
        }
    }

    /** Gets the classpath to be used for this compilation. */
    public Path getClasspath() {
        return _compileClasspath;
    }

    /**
     * Adds a path to the classpath.
     */
    public Path createClasspath() {
        if (_compileClasspath == null) {
            _compileClasspath = new Path(project);
        }
        return _compileClasspath.createPath();
    }

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

    /**
     * Adds a reference to a classpath defined elsewhere.
     */
    public void setClasspathRef(Reference r) {
        createClasspath().setRefid(r);
    }


    /**
     * The format to write the output in, "xml" or "text".
     *
     * @param ea
     */
    public void setFormat(FormatAttribute ea) {
        format = ea.getValue();
    }

    public static class FormatAttribute extends EnumeratedAttribute {
        private String [] formats = new String[]{"xml", "text"};

        public String[] getValues() {
            return formats;
        }
    }


    /**
     * No problems with this test.
     */
    private static final int SUCCESS = 0;
    /**
     * An error occured.
     */
    private static final int ERRORS = 1;

    public void execute() throws BuildException {

        CommandlineJava commandline = new CommandlineJava();

        if ("text".equals(format)) {
            commandline.setClassname("jdepend.textui.JDepend");
        } else
        if ("xml".equals(format)) {
            commandline.setClassname("jdepend.xmlui.JDepend");
        }

        if (_jvm != null) {
            commandline.setVm(_jvm);
        }

        if (getSourcespath() == null) {
            throw new BuildException("Missing Sourcepath required argument");
        }

        // execute the test and get the return code
        int exitValue = JDependTask.ERRORS;
        boolean wasKilled = false;
        if (!getFork()) {
            exitValue = executeInVM(commandline);
        } else {
            ExecuteWatchdog watchdog = createWatchdog();
            exitValue = executeAsForked(commandline, watchdog);
            // null watchdog means no timeout, you'd better not check with null
            if (watchdog != null) {
                //info will be used in later version do nothing for now
                //wasKilled = watchdog.killedProcess();
            }
        }

        // if there is an error/failure and that it should halt, stop 
        // everything otherwise just log a statement
        boolean errorOccurred = exitValue == JDependTask.ERRORS;

        if (errorOccurred) {
            if  (getHaltonerror()) {
                throw new BuildException("JDepend failed",
                                         location);
            } else {
                log("JDepend FAILED", Project.MSG_ERR);
            }
        }
    }



    // this comment extract from JUnit Task may also apply here
    // "in VM is not very nice since it could probably hang the
    // whole build. IMHO this method should be avoided and it would be best
    // to remove it in future versions. TBD. (SBa)"

    /**
     * Execute inside VM.
     */
    public int executeInVM(CommandlineJava commandline) throws BuildException {
        jdepend.textui.JDepend jdepend;

        if ("xml".equals(format)) {
            jdepend = new jdepend.xmlui.JDepend();
        } else {
            jdepend = new jdepend.textui.JDepend();
        }

        if (getOutputFile() != null) {
            FileWriter fw;
            try {
                fw = new FileWriter(getOutputFile().getPath());
            } catch (IOException e) {
                String msg = "JDepend Failed when creating the output file: " 
                    + e.getMessage();
                log(msg);
                throw new BuildException(msg);
            }
            jdepend.setWriter(new PrintWriter(fw));
            log("Output to be stored in " + getOutputFile().getPath());
        }

        PathTokenizer sourcesPath 
            = new PathTokenizer(getSourcespath().toString());
        while (sourcesPath.hasMoreTokens()) {
            File f = new File(sourcesPath.nextToken());

            // not necessary as JDepend would fail, but why loose some time?
            if (!f.exists() || !f.isDirectory()) {
                String msg = "\"" + f.getPath() + "\" does not represent a valid" 
                    + " directory. JDepend would fail.";
                log(msg);
                throw new BuildException(msg);
            }
            try {
                jdepend.addDirectory(f.getPath());
            } catch (IOException e) {
                String msg = "JDepend Failed when adding a source directory: " 
                    + e.getMessage();
                log(msg);
                throw new BuildException(msg);
            }
        }
        jdepend.analyze();
        return SUCCESS;
    }


    /**
     * Execute the task by forking a new JVM. The command will block until
     * it finishes. To know if the process was destroyed or not, use the
     * <tt>killedProcess()</tt> method of the watchdog class.
     * @param  watchdog   the watchdog in charge of cancelling the test if it
     * exceeds a certain amount of time. Can be <tt>null</tt>, in this case
     * the test could probably hang forever.
     */
    // JL: comment extracted from JUnitTask (and slightly modified)
    public int executeAsForked(CommandlineJava commandline,
                               ExecuteWatchdog watchdog) throws BuildException {
        // if not set, auto-create the ClassPath from the project
        createClasspath();

        // not sure whether this test is needed but cost nothing to put.
        // hope it will be reviewed by anybody competent
        if (getClasspath().toString().length() > 0) {
            createJvmarg(commandline).setValue("-classpath");
            createJvmarg(commandline).setValue(getClasspath().toString());
        }

        if (getOutputFile() != null) {
            // having a space between the file and its path causes commandline 
            // to add quotes around the argument thus making JDepend not taking 
            // it into account. Thus we split it in two
            commandline.createArgument().setValue("-file");
            commandline.createArgument().setValue(_outputFile.getPath());
            // we have to find a cleaner way to put this output
        }

        PathTokenizer sourcesPath 
            = new PathTokenizer(getSourcespath().toString());
        while (sourcesPath.hasMoreTokens()) {
            File f = new File(sourcesPath.nextToken());

            // not necessary as JDepend would fail, but why loose some time?
            if (!f.exists() || !f.isDirectory()) {
                throw new BuildException("\"" + f.getPath() + "\" does not " 
                    + "represent a valid directory. JDepend would fail.");
            }
            commandline.createArgument().setValue(f.getPath());
        }

        Execute execute = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN), watchdog);
        execute.setCommandline(commandline.getCommandline());
        if (getDir() != null) {
            execute.setWorkingDirectory(getDir());
            execute.setAntRun(project);
        }

        if (getOutputFile() != null) {
            log("Output to be stored in " + getOutputFile().getPath());
        }
        log(commandline.describeCommand(), Project.MSG_VERBOSE);
        try {
            return execute.execute();
        } catch (IOException e) {
            throw new BuildException("Process fork failed.", e, location);
        }
    }

    /**
     * @return <tt>null</tt> if there is a timeout value, otherwise the
     * watchdog instance.
     */
    protected ExecuteWatchdog createWatchdog() throws BuildException {

        return null;
        /*
          if (getTimeout() == null){
          return null;
          }
          return new ExecuteWatchdog(getTimeout().intValue());
        */
    }
}
