/*   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.BuildException;
import org.apache.tools.ant.FileScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Jar;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.common.IOUtil;

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

/**
 * Modeled after Ant's javac and zip tasks.
 * <p>
 * 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.
 */

@SuppressWarnings("unused")
public class XMLBean extends MatchingTask {
    private final List<FileSet> schemas = new ArrayList<>();

    private Set<String> 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,
        repackage,
        partialMethods;

    private final List<Extension> extensions = new ArrayList<>();

    private final Map<String, Set<File>> _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(getProject()) == 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(getProject()) != null) {
            schemas.add(fileset);
        }

        for (FileSet fs : schemas) {
            FileScanner scanner = fs.getDirectoryScanner(getProject());
            File basedir = scanner.getBasedir();
            String[] paths = scanner.getIncludedFiles();

            processPaths(paths, basedir);
        }

        Set<File> xsdList = _extRouter.get(XSD);
        Set<File> wsdlList = _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<File> javaList = _extRouter.get(JAVA);
        Set<File> xsdconfigList = _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 = xsdList.toArray(new File[0]);
        File[] wsdlArray = wsdlList.toArray(new File[0]);
        File[] javaArray = javaList.toArray(new File[0]);
        File[] xsdconfigArray = xsdconfigList.toArray(new File[0]);
        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(getProject());
                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
            Parameters params = new 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.setRepackage(repackage);
            params.setPartialMethods(SchemaCompiler.parsePartialMethods(partialMethods));
            success = SchemaCompiler.compile(params);

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

                // compile the source
                Javac javac = new Javac();
                javac.setProject(getProject());
                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.setSource("1.8");
                javac.setTarget("1.8");
                javac.setIncludeantruntime(includeAntRuntime);
                javac.setIncludejavaruntime(includeJavaRuntime);
                javac.setNowarn(nowarn);
                javac.setSrcdir(new Path(getProject(), 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(getProject());
                    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 (String s : paths) {
            int dot = s.lastIndexOf('.');
            if (dot > -1) {
                String possExt = s.substring(dot).toLowerCase(Locale.ROOT);
                Set<File> set = _extRouter.get(possExt);

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

    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(getProject());
        }
        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(getProject());
        }

        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.
     * <p>
     * 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 org.apache.xmlbeans.impl.tool.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() {
        return mdefnamespaces == null ? null : String.join(",", mdefnamespaces);

    }

    /**
     * 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 noext Ignore extensions
     */
    public void setNoExt(boolean noext) {
        this.noext = noext;
    }

    public boolean isNoExt() {
        return noext;
    }

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

    public String getRepackage() {
        return repackage;
    }

    public void setRepackage(String repackage) {
        this.repackage = repackage;
    }

    public String getPartialMethods() {
        return partialMethods;
    }

    /**
     * Comma separated list of bean methods to be generated. Use "-" to negate and "ALL" for all.
     * processed left-to-right, e.g. "ALL,-GET_LIST" exclude java.util.List getters
     *
     * @see XmlOptions.BeanMethod
     */
    public void setPartialMethods(String partialMethods) {
        this.partialMethods = partialMethods;
    }

    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<XmlError> {
        private final boolean _noisy;
        private final URI _baseURI;

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

        public boolean add(XmlError err) {
            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<XmlError> iterator() {
            return Collections.emptyIterator();
        }

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