/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 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 acknowledgment:  
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" 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 
*    XMLBeans", nor may "Apache" appear in their name, without prior 
*    written permission of the Apache Software Foundation.
*
* 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 and was
* originally based on software copyright (c) 2000-2003 BEA Systems 
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/

package org.apache.xmlbeans.impl.tool;

import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.taskdefs.Jar;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.FileScanner;
import org.apache.tools.ant.Project;

import java.io.File;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.util.*;
import java.net.URI;

import org.apache.xmlbeans.XmlError;

/**
 * Modeled after Ant's javac and zip tasks.
 *
 * Schema files to process, or directories of schema files, are set with the 'schema'
 * attribute, and can be filtered with 'includes' and 'excludes'.
 * Alternatively, one or more nested &lt;fileset&gt; elements can specify the 
 * files and directories to be used to generate this XMLBean.
 * The include set can also define .java files that should be built as well.  
 * See the FileSet documentation at http://jakarta.apache.org/ant/manual/index.html
 * for instructions on FileSets if you are unfamiliar with their usage.
 */

public class XMLBean extends MatchingTask
{
    private ArrayList   schemas = new ArrayList();
    
    private Path        classpath;
    
    private File        destfile,
                        schema,
                        srcgendir,
                        classgendir;
    
    private boolean     quiet,
                        verbose,
                        debug,
                        optimize,
                        download,
                        srconly,
                        failonerror = true,
                        fork = true,
                        includeAntRuntime = true,
                        includeJavaRuntime = false;
    
    private String      typesystemname,
                        forkedExecutable,
                        compiler,
                        debugLevel,
                        memoryInitialSize,
                        memoryMaximumSize;
    
    private List        extensions = new ArrayList();

    private HashMap     _extRouter = new HashMap(5);

    private static final String XSD = ".xsd",
                                WSDL = ".wsdl",
                                JAVA = ".java",
                                XSDCONFIG = ".xsdconfig";


    public void execute() throws BuildException
    {
        /* VALIDATION */
        //required
        if (schemas.size() == 0
            && schema == null
            && fileset.getDir(project) == null)
        {
            String msg = "The 'schema' or 'dir' attribute or a nested fileset is required.";
            if (failonerror)
                throw new BuildException(msg);
            else
            {
                log(msg, Project.MSG_ERR);
                return;
            }
        }
        
        _extRouter.put(XSD, new HashSet());
        _extRouter.put(WSDL, new HashSet());
        _extRouter.put(JAVA, new HashSet());
        _extRouter.put(XSDCONFIG, new HashSet());

        File theBasedir = schema;

        if (schema != null)
        {
            if (schema.isDirectory())
            {
                FileScanner scanner = getDirectoryScanner(schema);
                String[] paths = scanner.getIncludedFiles();
                processPaths(paths, scanner.getBasedir());
            }
            else
            {
                theBasedir = schema.getParentFile();
                processPaths(new String[] { schema.getName() }, theBasedir);
            }
        }
        
        if (fileset.getDir(project) != null)
            schemas.add(fileset);
        
        Iterator si = schemas.iterator();
        while (si.hasNext())
        {
            FileSet fs = (FileSet) si.next();
            FileScanner scanner = fs.getDirectoryScanner(project);
            File basedir = scanner.getBasedir();
            String[] paths = scanner.getIncludedFiles();

            processPaths(paths, basedir);
        }

        Set xsdList = (Set) _extRouter.get(XSD);
        Set wsdlList = (Set) _extRouter.get(WSDL);
        
        if (xsdList.size() + wsdlList.size() == 0)
        {
            log("Could not find any xsd or wsdl files to process.", Project.MSG_WARN);
            return;
        }

        //optional
        Set javaList = (Set) _extRouter.get(JAVA);
        Set xsdconfigList = (Set) _extRouter.get(XSDCONFIG);

        if (srcgendir == null && srconly)
            srcgendir = classgendir;

        if (destfile == null && classgendir == null && ! srconly)
            destfile = new File("xmltypes.jar");

        if (verbose)
            quiet = false;

        /* EXECUTION */

        File[] xsdArray = (File[]) xsdList.toArray(new File[xsdList.size()]);
        File[] wsdlArray = (File[]) wsdlList.toArray(new File[wsdlList.size()]);
        File[] javaArray = (File[]) javaList.toArray(new File[javaList.size()]);
        File[] xsdconfigArray = (File[]) xsdconfigList.toArray(new File[xsdconfigList.size()]);
        ErrorLogger err = new ErrorLogger(verbose);

        boolean success = false;

        try
        {
            // create a temp directory
            File tmpdir = null;
            if (srcgendir == null || classgendir == null)
            {
                tmpdir = SchemaCodeGenerator.createTempDir();
            }
            if (srcgendir == null)
                srcgendir = SchemaCodeGenerator.createDir(tmpdir, "src");
            if (classgendir == null)
                classgendir = SchemaCodeGenerator.createDir(tmpdir, "classes");
            
            // use the system classpath if user didn't provide any
            if (classpath == null)
            {
                classpath = new Path(project);
                classpath.concatSystemClasspath();
            }
        
            // prepend the output directory on the classpath
            Path.PathElement pathElement = classpath.createPathElement();
            pathElement.setLocation(classgendir);
        
            String[] paths = classpath.list();
            File[] cp = new File[paths.length];
            for (int i = 0; i < paths.length; i++)
                cp[i] = new File(paths[i]);
        
            // generate the source
            SchemaCompiler.Parameters params = new SchemaCompiler.Parameters();
            params.setBaseDir(theBasedir);
            params.setXsdFiles(xsdArray);
            params.setWsdlFiles(wsdlArray);
            params.setJavaFiles(javaArray);
            params.setConfigFiles(xsdconfigArray);
            params.setClasspath(cp);
            //params.setOutputJar(destfile); // always use the jar task below
            params.setName(typesystemname);
            params.setSrcDir(srcgendir);
            params.setClassesDir(classgendir);
            params.setNojavac(true); // always compile using javac task below
            params.setDebug(debug);
            params.setVerbose(verbose);
            params.setQuiet(quiet);
            params.setDownload(download);
            params.setExtensions(extensions);
            params.setErrorListener(err);
            success = SchemaCompiler.compile(params);

            if (success && !srconly) {
                long start = System.currentTimeMillis();

                // compile the source
                Javac javac = new Javac();
                javac.setProject(project);
                javac.setTaskName(getTaskName());
                javac.setClasspath(classpath);
                if (compiler != null) javac.setCompiler(compiler);
                javac.setDebug(debug);
                if (debugLevel != null) javac.setDebugLevel(debugLevel);
                javac.setDestdir(classgendir);
                javac.setExecutable(forkedExecutable);
                javac.setFailonerror(failonerror);
                javac.setFork(fork);
                javac.setIncludeantruntime(includeAntRuntime);
                javac.setIncludejavaruntime(includeJavaRuntime);
                javac.setSrcdir(new Path(project, srcgendir.getAbsolutePath()));
                if (memoryInitialSize != null) javac.setMemoryInitialSize(memoryInitialSize);
                if (memoryMaximumSize != null) javac.setMemoryMaximumSize(memoryMaximumSize);
                javac.setOptimize(optimize);
                javac.setVerbose(verbose);
                javac.execute();

                long finish = System.currentTimeMillis();
                if (!quiet)
                    log("Time to compile code: " + ((double)(finish - start) / 1000.0) + " seconds");

                if (destfile != null)
                {
                    // jar the compiled classes
                    Jar jar = new Jar();
                    jar.setProject(project);
                    jar.setTaskName(getTaskName());
                    jar.setBasedir(classgendir);
                    jar.setDestFile(destfile);
                    jar.execute();
                }
            }

            if (tmpdir != null) {
                SchemaCodeGenerator.tryHardToDelete(tmpdir);
            }
        }
        catch (Throwable e)
        {
            //interrupted means cancel
            if (e instanceof InterruptedException)
                throw new BuildException(e);
            
            log("Exception while building schemas: " + e.getMessage(), Project.MSG_ERR);
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            log(sw.toString(), Project.MSG_VERBOSE);
        }

        if (!success && failonerror)
            throw new BuildException(); //stop the build
    }

    private void processPaths(String[] paths, File baseDir)
    {
        for (int i = 0; i < paths.length; i++)
        {
            int dot = paths[i].lastIndexOf('.');
            if (dot > -1)
            {
                String path = paths[i];
                String possExt = path.substring(dot).toLowerCase();
                Set set = (Set) _extRouter.get(possExt);

                if (set != null)
                    set.add(new File(baseDir, path));
            }
        }
    }

    public void addFileset(FileSet fileset)
    {
        schemas.add(fileset);
    }

    /////////////////////////////
    //Getter/Setters
    public File getSchema()
    {
        return schema;
    }

    /**
     * A file that points to either an individual schema file or a directory of files.
     * It is optional only if one or more &lt;fileset&gt; elements are nested in this
     * task.
     * @param schema Required, unless a fileset element is nested.
     */
    public void setSchema(File schema)
    {
        this.schema = schema;
    }

    /**
     * The classpath to use if schemas in the fileset import definitions that are
     * supplied by other compiled xml beans JAR files, or if .java files are in the
     * schema fileset.
     * @param classpath Optional.
     */ 
    public void setClasspath(Path classpath)
    {
        if (this.classpath != null)
            this.classpath.append(classpath);
        else
            this.classpath = classpath;
    }
    
    /**
     * Adds a path to the classpath.
     */
    public Path createClasspath() {
        if (classpath == null) {
            classpath = new Path(project);
        }
        return classpath.createPath();
    }

    /**
     * Adds a reference to a classpath defined elsewhere.
     * @param classpathref Optional.
     */
    public void setClasspathRef(Reference classpathref)
    {
        if (classpath == null)
            classpath = new Path(project);
        
        classpath.createPath().setRefid(classpathref);
    }
    
    public Path getClasspath()
    {
        return classpath;
    }

    public File getDestfile()
    {
        return destfile;
    }

    /**
     * Define the name of the jar file created.  For instance, "myXMLBean.jar"
     * will output the results of this task into a jar with the same name.
     * Optional, defaults to "xmltypes.jar".
     * @param destfile Optional.
     */ 
    public void setDestfile(File destfile)
    {
        this.destfile = destfile;
    }

    public File getSrcgendir()
    {
        return srcgendir;
    }

    /**
     * Set a location to generate .java files into.  Optional, defaults to
     * a temp dir.
     * @param srcgendir Optional.
     */ 
    public void setSrcgendir(File srcgendir)
    {
        this.srcgendir = srcgendir;
    }

    public File getClassgendir()
    {
        return classgendir;
    }

    /**
     * Set a location to generate .class files into.  Optional, defaults to
     * a temp dir.
     * @param classgendir Optional.
     */ 
    public void setClassgendir(File classgendir)
    {
        this.classgendir = classgendir;
    }

    /**
     * Choose the implementation for this particular task.
     *
     * @since Ant 1.5
     */
    public void setCompiler(String compiler)
    {
        this.compiler = compiler;
    }
    
    public boolean isDownload()
    {
        return download;
    }

    /**
     * Set to true to permit the compiler to download URLs for imports
     * and includes.  Defaults to false, meaning all imports and includes
     * must be copied locally.
     * @param download Optional.
     */
    public void setDownload(boolean download)
    {
        this.download = download;
    }

    /**
     * If true, compiles with optimization enabled.
     */
    public void setOptimize(boolean optimize) {
        this.optimize = optimize;
    }

    /** Gets the optimize flag. */
    public boolean getOptimize() {
        return optimize;
    }

    public boolean isVerbose()
    {
        return verbose;
    }

    /**
     * Controls the amount of output.  Defaults to true.
     * @param verbose Optional.
     */ 
    public void setVerbose(boolean verbose)
    {
        this.verbose = verbose;
    }

    public boolean isQuiet()
    {
        return quiet;
    }

    /**
     * Controls the amount of output.  Defaults to false.
     * @param quiet Optional.
     */ 
    public void setQuiet(boolean quiet)
    {
        this.quiet = quiet;
    }

    public boolean isDebug()
    {
        return debug;
    }

    /**
     * Get the value of debugLevel.
     * @return value of debugLevel.
     */
    public String getDebugLevel() {
        return debugLevel;
    }

    /**
     * Keyword list to be appended to the -g command-line switch.
     *
     * This will be ignored by all implementations except modern
     * and classic(ver >= 1.2). Legal values are none or a
     * comma-separated list of the following keywords: lines, vars,
     * and source. If debuglevel is not specified, by default, :none
     * will be appended to -g. If debug is not turned on, this attribute
     * will be ignored.
     *
     * @param v  Value to assign to debugLevel.
     */
    public void setDebugLevel(String  v) {
        this.debugLevel = v;
    }

    /**
     * Generate debugging symbols.
     * @param debug Optional.
     */ 
    public void setDebug(boolean debug)
    {
        this.debug = debug;
    }

    /**
     * If true, forks the javac compiler.
     *
     * @param f "true|false|on|off|yes|no"
     */
    public void setFork(boolean f) {
        fork = f;
    }

    /**
     * Sets the the name of the javac executable.
     *
     * <p>Ignored unless fork is true or extJavac has been specified
     * as the compiler.</p>
     */
    public void setExecutable(String forkExec) {
        forkedExecutable = forkExec;
    }

    public String getExecutable() {
        return forkedExecutable;
    }

    public boolean isSrconly()
    {
        return srconly;
    }

    /**
     * A value of true means that only source will be generated.  Optional,
     * default is false.
     * @param srconly Optional.
     */ 
    public void setSrconly(boolean srconly)
    {
        this.srconly = srconly;
    }
 
    public String getTypesystemname()
    {
        return typesystemname;
    }

    /**
     * One or more SchemaCompiler extensions can be passed in via the &lt;extension> subelement.
     *  Schema Compiler extensions must implement the interface com.xbean.too.SchemaCompilerExtension
     */
    public Extension createExtension() {
        Extension e = new Extension();
        extensions.add(e);
        return e;
    }

    /**
     * The name of the package that the TypeSystemHolder class should be 
     * generated in. Normally this should be left unspecified.  None of
     * the xml beans are generated in this package.
     * <BR><BR>Use .xsdconfig files to modify xml bean package or class names.
     * @param typesystemname Optional.
     */ 
    public void setTypesystemname(String typesystemname)
    {
        this.typesystemname = typesystemname;
    }

    public boolean isFailonerror()
    {
        return failonerror;
    }

    /**
     * Determines whether or not the ant target will continue if the XMLBean
     * creation encounters a build error.  Defaults to true.  Optional.
     * @param failonerror Optional.
     */ 
    public void setFailonerror(boolean failonerror)
    {
        this.failonerror = failonerror;
    }

    public boolean isIncludeAntRuntime()
    {
        return includeAntRuntime;
    }

    public void setIncludeAntRuntime(boolean includeAntRuntime)
    {
        this.includeAntRuntime = includeAntRuntime;
    }

    public boolean isIncludeJavaRuntime()
    {
        return includeJavaRuntime;
    }

    public void setIncludeJavaRuntime(boolean includeJavaRuntime)
    {
        this.includeJavaRuntime = includeJavaRuntime;
    }

    /**
     * Set the initial memory size of the underlying javac process.
     */
    public String getMemoryInitialSize()
    {
        return memoryInitialSize;
    }

    public void setMemoryInitialSize(String memoryInitialSize)
    {
        this.memoryInitialSize = memoryInitialSize;
    }

    /**
     * Set the maximum memory size of the underlying javac process.
     */
    public String getMemoryMaximumSize()
    {
        return memoryMaximumSize;
    }

    public void setMemoryMaximumSize(String memoryMaximumSize)
    {
        this.memoryMaximumSize = memoryMaximumSize;
    }

    private static URI uriFromFile(File f)
    {
        if (f == null)
            return null;

        try
        {
            return f.getCanonicalFile().toURI();
        }
        catch(java.io.IOException e)
        {
            // Don't spit out an exception here because on Windows you'll get one
            // if the filename is "aux", "lpt1", etc. It's the caller's responsibility
            // to deal with those cases correctly, usually by calling FileSvc.invalidPathCheck()
            // MessageSvc.get().logException(e);
            return f.getAbsoluteFile().toURI();
        }
    }

    public class ErrorLogger extends AbstractCollection
    {
        private boolean _noisy;
        private URI _baseURI;

        public ErrorLogger(boolean noisy)
        {
            _noisy = noisy;
            _baseURI = uriFromFile(project.getBaseDir());
        }

        public boolean add(Object o)
        {
            if (o instanceof XmlError)
            {
                XmlError err = (XmlError)o;
                if (err.getSeverity() == XmlError.SEVERITY_ERROR)
                    log(err.toString(_baseURI), Project.MSG_ERR);
                else if (err.getSeverity() == XmlError.SEVERITY_WARNING)
                    log(err.toString(_baseURI), Project.MSG_WARN);
                else if (_noisy)
                    log(err.toString(_baseURI), Project.MSG_INFO);
            }
            return false;
        }

        public Iterator iterator()
        {
            return Collections.EMPTY_LIST.iterator();
        }

        public int size()
        {
            return 0;
        }
    }
}
