/*
 * 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/>.
 */
/*
 *  build notes
 *  -The reference CD to listen to while editing this file is
 *  nap: Underworld  - Everything, Everything
 *  -variable naming policy from Fowler's refactoring book.
 *  -tested against the PDC pre-beta of csc.exe; future versions will
 *  inevitably change things
 */
// ====================================================================
// place in the optional ant tasks package
// but in its own dotnet group
// ====================================================================

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

// ====================================================================
// imports
// ====================================================================

import java.io.File;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.MatchingTask;

/**
 *  Task to assemble .net 'Intermediate Language' files. The task will only work
 *  on win2K until other platforms support csc.exe or an equivalent. ilasm.exe
 *  must be on the execute path too. <p>
 *
 *  <p>
 *
 *  All parameters are optional: &lt;il/&gt; should suffice to produce a debug
 *  build of all *.il files. The option set is roughly compatible with the
 *  CSharp class; even though the command line options are only vaguely
 *  equivalent. [The low level commands take things like /OUT=file, csc wants
 *  /out:file ... /verbose is used some places; /quiet here in ildasm... etc.]
 *  It would be nice if someone made all the command line tools consistent (and
 *  not as brittle as the java cmdline tools) <p>
 *
 *  The task is a directory based task, so attributes like <b>includes="*.il"
 *  </b> and <b>excludes="broken.il"</b> can be used to control the files pulled
 *  in. Each file is built on its own, producing an appropriately named output
 *  file unless manually specified with <b>outfile</b>
 *
 *@author     Steve Loughran steve_l@iseran.com
 *@version    0.5
 */

public class Ilasm
         extends MatchingTask {

    /**
     *  Name of the executable. The .exe suffix is deliberately not included in
     *  anticipation of the unix version
     */
    protected static final String exe_name = "ilasm";

    /**
     *  what is the file extension we search on?
     */
    protected static final String file_ext = "il";

    /**
     *  and now derive the search pattern from the extension
     */
    protected static final String file_pattern = "**/*." + file_ext;

    /**
     *  title of task for external presentation
     */
    protected static final String exe_title = "ilasm";

    /**
     *  source directory upon which the search pattern is applied
     */
    private File srcDir;

    /**
     *  type of target. Should be one of exe|library|module|winexe|(null)
     *  default is exe; the actual value (if not null) is fed to the command
     *  line. <br>
     *  See /target
     */
    protected String targetType;

    /**
     *  verbose flag
     */
    protected boolean verbose;

    /**
     *  listing flag
     */

    protected boolean listing;

    /**
     *  output file. If not supplied this is derived from the source file
     */
    protected File outputFile;

    /**
     *  resource file (.res format) to include in the app.
     */
    protected File resourceFile;

    /**
     *  flag to control action on execution trouble
     */
    protected boolean failOnError;

    /**
     *  debug flag. Controls generation of debug information.
     */
    protected boolean debug;

    /**
     *  file containing private key
     */

    private File keyfile;

    /**
     *  any extra command options?
     */
    protected String extraOptions;


    /**
     *  constructor inits everything and set up the search pattern
     */
    public Ilasm() {
        Clear();
        setIncludes(file_pattern);
    }


    /**
     *  reset all contents.
     */
    public void Clear() {
        targetType = null;
        srcDir = null;
        listing = false;
        verbose = false;
        debug = true;
        outputFile = null;
        failOnError = true;
        resourceFile = null;
        extraOptions = null;
    }


    /**
     *  Set the source dir to find the files to be compiled
     *
     *@param  srcDirName  The new SrcDir value
     */
    public void setSrcDir(File srcDirName) {
        srcDir = srcDirName;
    }


    /**
     *  define the target
     *
     *@param  targetType          one of exe|library|
     *@exception  BuildException  if target is not one of
     *      exe|library|module|winexe
     */

    public void setTargetType(String targetType)
             throws BuildException {
        this.targetType = targetType.toLowerCase();
        if (targetType.equals("exe") || targetType.equals("library")) {
            targetType = targetType;
        } else {
            throw new BuildException("targetType " + targetType + " is not a valid type");
        }
    }


    /**
     *  accessor method for target type
     *
     *@return    the current target option
     */
    public String getTargetType() {
        return targetType;
    }


    /**
     *  g get the target type or null for no argument needed
     *
     *@return    The TargetTypeParameter value
     */

    protected String getTargetTypeParameter() {
        if (!notEmpty(targetType)) {
            return null;
        }
        if (targetType.equals("exe")) {
            return "/exe";
        } else if (targetType.equals("library")) {
            return "/dll";
        } else {
            return null;
        }
    }


    /**
     *  Sets the Owner attribute
     *
     *@param  s  The new Owner value
     */

    public void setOwner(String s) {
        log("This option is not supported by ILASM as of Beta-2, and will be ignored", Project.MSG_WARN);
    }


    /**
     *  test for a string containing something useful
     *
     *@param  s       any string
     *@return         true if the argument is not null or empty
     */
    protected boolean notEmpty(String s) {
        return s != null && s.length() != 0;
    }


    /**
     *  enable/disable verbose ILASM output
     *
     *@param  b  flag set to true for verbose on
     */
    public void setVerbose(boolean b) {
        verbose = b;
    }


    /**
     *  turn the verbose flag into a parameter for ILASM
     *
     *@return    null or the appropriate command line string
     */
    protected String getVerboseParameter() {
        return verbose ? null : "/quiet";
    }


    /**
     *  enable/disable listing
     *
     *@param  b  flag set to true for listing on
     */
    public void setListing(boolean b) {
        listing = b;
    }


    /**
     *  turn the listing flag into a parameter for ILASM
     *
     *@return    the appropriate string from the state of the listing flag
     */
    protected String getListingParameter() {
        return listing ? "/listing" : "/nolisting";
    }


    /**
     *  Set the output file
     *
     *@param  params  The new outputFile value
     */
    public void setOutputFile(File params) {
        outputFile = params;
    }


    /**
     *  get the output file
     *
     *@return    the argument string or null for no argument
     */
    protected String getOutputFileParameter() {
        if (outputFile == null || outputFile.length() == 0) {
            return null;
        }
        File f = outputFile;
        return "/output=" + f.toString();
    }


    /**
     *  Set the resource file
     *
     *@param  fileName  path to the file. Can be relative, absolute, whatever.
     */
    public void setResourceFile(File fileName) {
        resourceFile = fileName;
    }


    /**
     *  Gets the resourceFileParameter attribute of the Ilasm task
     *
     *@return    The resourceFileParameter value
     */
    protected String getResourceFileParameter() {
        if (resourceFile != null) {
            return "/resource=" + resourceFile.toString();
        } else {
            return null;
        }
    }


    /**
     *  set fail on error flag
     *
     *@param  b  The new failOnError value
     */
    public void setFailOnError(boolean b) {
        failOnError = b;
    }


    /**
     *  query fail on error flag
     *
     *@return    The failFailOnError value
     */
    public boolean getFailFailOnError() {
        return failOnError;
    }


    /**
     *  set the debug flag on or off
     *
     *@param  f  on/off flag
     */
    public void setDebug(boolean f) {
        debug = f;
    }


    /**
     *  query the debug flag
     *
     *@return    true if debug is turned on
     */
    public boolean getDebug() {
        return debug;
    }


    /**
     *  get the argument or null for no argument needed
     *
     *@return    The debugParameter value
     */
    protected String getDebugParameter() {
        return debug ? "/debug" : null;
    }


    /**
     *  Sets the keyfile attribute of the Ilasm object
     *
     *@param  keyfile  The new keyfile value
     */
    public void setKeyfile(File keyfile) {
        this.keyfile = keyfile;
    }


    /**
     *  get the argument or null for no argument needed
     *
     *@return    The keyfileParameter value
     */
    protected String getKeyfileParameter() {
        if (keyfile != null) {
            return "/keyfile:" + keyfile.toString();
        } else {
            return null;
        }
    }


    /**
     *  Sets the ExtraOptions attribute
     *
     *@param  extraOptions  The new ExtraOptions value
     */
    public void setExtraOptions(String extraOptions) {
        this.extraOptions = extraOptions;
    }


    /**
     *  Gets the ExtraOptions attribute
     *
     *@return    The ExtraOptions value
     */
    public String getExtraOptions() {
        return this.extraOptions;
    }


    /**
     *  get any extra options or null for no argument needed
     *
     *@return    The ExtraOptions Parameter to CSC
     */
    protected String getExtraOptionsParameter() {
        if (extraOptions != null && extraOptions.length() != 0) {
            return extraOptions;
        } else {
            return null;
        }
    }


    /**
     *  This is the execution entry point. Build a list of files and call ilasm
     *  on each of them.
     *
     *@throws  BuildException  if the assembly failed and FailOnError is true
     */
    public void execute()
             throws BuildException {
        if (srcDir == null) {
            srcDir = project.resolveFile(".");
        }

        //get dependencies list.
        DirectoryScanner scanner = super.getDirectoryScanner(srcDir);
        String[] dependencies = scanner.getIncludedFiles();
        log("assembling " + dependencies.length + " file" + ((dependencies.length == 1) ? "" : "s"));
        String baseDir = scanner.getBasedir().toString();
        //add to the command
        for (int i = 0; i < dependencies.length; i++) {
            String targetFile = dependencies[i];
            targetFile = baseDir + File.separator + targetFile;
            executeOneFile(targetFile);
        }

    }
    // end execute


    /**
     *  do the work for one file by building the command line then calling it
     *
     *@param  targetFile       name of the the file to assemble
     *@throws  BuildException  if the assembly failed and FailOnError is true
     */
    public void executeOneFile(String targetFile)
             throws BuildException {
        NetCommand command = new NetCommand(this, exe_title, exe_name);
        command.setFailOnError(getFailFailOnError());
        //DEBUG helper
        command.setTraceCommandLine(true);
        //fill in args
        command.addArgument(getDebugParameter());
        command.addArgument(getTargetTypeParameter());
        command.addArgument(getListingParameter());
        command.addArgument(getOutputFileParameter());
        command.addArgument(getResourceFileParameter());
        command.addArgument(getVerboseParameter());
        command.addArgument(getKeyfileParameter());
        command.addArgument(getExtraOptionsParameter());

        /*
         *  space for more argumentativeness
         *  command.addArgument();
         *  command.addArgument();
         */
        command.addArgument(targetFile);
        //now run the command of exe + settings + file
        command.runCommand();
    }
    // end executeOneFile
}

