/*   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.URI;

import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.impl.common.IOUtil;

/**
 * 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,
                        noupa,
                        nopvr,
                        noann,
                        novdoc,
                        noext = false,
                        failonerror = true,
                        fork = true,
                        includeAntRuntime = true,
                        noSrcRegen,
                        includeJavaRuntime = false,
                        nowarn = false;

    private String      typesystemname,
                        forkedExecutable,
                        compiler,
                        debugLevel,
                        memoryInitialSize,
                        memoryMaximumSize,
                        catalog,
                        javasource;

    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 = IOUtil.createDir(tmpdir, "src");
            if (classgendir == null)
                classgendir = IOUtil.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.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.setCatalogFile(catalog);
            params.setIncrementalSrcGen(noSrcRegen);
            params.setMdefNamespaces(mdefnamespaces);
            params.setNoUpa(noupa);
            params.setNoPvr(nopvr);
            params.setNoAnn(noann);
            params.setNoVDoc(novdoc);
            params.setNoExt(noext);
            params.setJavaSource(javasource);
            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);
                if (javasource != null)
                {
                    javac.setSource(javasource);
                    javac.setTarget(javasource);
                }
                else
                {
                    javac.setSource("1.4");
                    javac.setTarget("1.4");
                }
                javac.setIncludeantruntime(includeAntRuntime);
                javac.setIncludejavaruntime(includeJavaRuntime);
                javac.setNowarn(nowarn);
                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 (BuildException e)
        {
            // re-throw anything thrown from javac or jar task
            throw e;
        }
        catch (Throwable e)
        {
            //interrupted means cancel
            if (e instanceof InterruptedException || failonerror)
                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;
    }

    public boolean isNowarn()
    {
        return nowarn;
    }

    public void setNowarn(boolean nowarn)
    {
        this.nowarn = nowarn;
    }

    public boolean isNoSrcRegen()
    {
        return noSrcRegen;
    }

    public void setNoSrcRegen(boolean noSrcRegen)
    {
        this.noSrcRegen = noSrcRegen;
    }

    /**
     * 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;
    }

    /**
     * Do not enforce the unique particle attribution rule.
     */
    public void setNoUpa(boolean noupa)
    {
        this.noupa = noupa;
    }

    public boolean isNoUpa()
    {
        return noupa;
    }

    /**
     * Do not enforce the particle valid (restriction) rule.
     */
    public void setNoPvr(boolean nopvr)
    {
        this.nopvr = nopvr;
    }

    public boolean isNoPvr()
    {
        return nopvr;
    }

    /**
     * Skip over schema &lt;annotation%gt; elements.
     */
    public void setNoAnnotations(boolean noann)
    {
        this.noann = noann;
    }

    public boolean isNoAnnotations()
    {
        return noann;
    }

    /**
     * Do not validate the contents of schema &lt;documentation&gt; elements.
     */
    public void setNoValidateDoc(boolean novdoc)
    {
        this.novdoc = novdoc;
    }

    public boolean isNoValidateDoc()
    {
        return novdoc;
    }

    /**
     * Ignore extensions found in .xsdconfig files
     * @param novdoc
     */
    public void setNoExt(boolean noext)
    {
        this.noext = noext;
    }

    public boolean isNoExt()
    {
        return noext;
    }

    /**
     * Generate java source compatible with the given version.  Currently,
     * only "1.4" or "1.5" are supported and "1.4" is the default.
     */
    public void setJavaSource(String javasource)
    {
        this.javasource = javasource;
    }

    public String getJavaSource()
    {
        return javasource;
    }

  //REVIEW this allows people to deal with the case where they drag in
  //more files for compilation than they should.  not sure if this is
  //a good thing or not
  private String source = null;
  public void setSource(String s) { source = s; }

    /**
     * Gets the XML Catalog file for org.apache.xml.resolver.tools.CatalogResolver. (Note: needs resolver.jar from http://xml.apache.org/commons/components/resolver/index.html)
     */
    public String getCatalog()
    {
        return catalog;
    }

    /**
     * Sets the XML Catalog file for org.apache.xml.resolver.tools.CatalogResolver. (Note: needs resolver.jar from http://xml.apache.org/commons/components/resolver/index.html)
     */
    public void setCatalog(String catalog)
    {
        this.catalog = catalog;
    }

    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;
        }
    }
}
