/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.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.URL;
import java.net.MalformedURLException;

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 Set         mdefnamespaces;

    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);
            params.setMdefNamespaces(mdefnamespaces);
            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;
    }

    /**
     * One or more namespaces in which duplicate definitions are to be ignored
     * can be passed in via the &lt;ignoreDuplicatesInNamespaces> subelement.
     */
    public void setIgnoreDuplicatesInNamespaces(String namespaces) {
        mdefnamespaces = new HashSet();
        StringTokenizer st = new StringTokenizer(namespaces, ",");
        while (st.hasMoreTokens())
        {
          String namespace = st.nextToken().trim();
          mdefnamespaces.add(namespace);
        }
    }

    public String getIgnoreDuplicatesInNamespaces() {
        if (mdefnamespaces == null) {
            return null;
        }
        StringBuffer buf = new StringBuffer();
        Iterator i = mdefnamespaces.iterator();
        while (i.hasNext()) {
            buf.append((String)i.next());
            if (i.hasNext()) {
                buf.append(",");
            }
        }
        return buf.toString();
    }

    /**
     * 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 URL urlFromFile(File f)
    {
        if (f == null)
            return null;

        try
        {
            return f.getCanonicalFile().toURL();
        }
        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);
            try
            {
                return f.getAbsoluteFile().toURL();
            }
            catch (MalformedURLException mue)
            {
                log(mue.toString(), Project.MSG_ERR);
                return null;
            }
        }
    }

    public class ErrorLogger extends AbstractCollection
    {
        private boolean _noisy;
        private URL _baseURL;

        public ErrorLogger(boolean noisy)
        {
            _noisy = noisy;
            _baseURL = urlFromFile(project.getBaseDir());
        }

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

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

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