/*   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.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.SchemaTypeSystem;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.impl.common.QNameHelper;

import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.HashMap;
import java.util.Map;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.io.File;

import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;

public class TypeHierarchyPrinter
{
    public static void printUsage()
    {
        System.out.println("Prints the inheritance hierarchy of types defined in a schema.\n");
        System.out.println("Usage: xsdtree [-noanon] [-nopvr] [-noupa] [-partial] [-license] schemafile.xsd*");
        System.out.println("    -noanon - Don't include anonymous types in the tree.");
        System.out.println("    -noupa - do not enforce the unique particle attribution rule");
        System.out.println("    -nopvr - do not enforce the particle valid (restriction) rule");
        System.out.println("    -partial - Print only part of the hierarchy.");
        System.out.println("    -license - prints license information");
        System.out.println("    schemafile.xsd - File containing the schema for which to print a tree.");
        System.out.println();
    }

    public static void main(String[] args) throws Exception
    {
        Set flags = new HashSet();
        flags.add("h");
        flags.add("help");
        flags.add("usage");
        flags.add("license");
        flags.add("version");
        flags.add("noanon");
        flags.add("noupr");
        flags.add("noupa");
        flags.add("partial");

        CommandLine cl = new CommandLine(args, flags, Collections.EMPTY_SET);
        if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null)
        {
            printUsage();
            System.exit(0);
            return;
        }

        String[] badopts = cl.getBadOpts();
        if (badopts.length > 0)
        {
            for (int i = 0; i < badopts.length; i++)
                System.out.println("Unrecognized option: " + badopts[i]);
            printUsage();
            System.exit(0);
            return;
        }

        if (cl.getOpt("license") != null)
        {
            CommandLine.printLicense();
            System.exit(0);
            return;
        }

        if (cl.getOpt("version") != null)
        {
            CommandLine.printVersion();
            System.exit(0);
            return;
        }

        if (cl.args().length == 0)
        {
            printUsage();
            return;
        }

        boolean noanon = (cl.getOpt("noanon") != null);
        boolean nopvr = (cl.getOpt("nopvr") != null);
        boolean noupa = (cl.getOpt("noupa") != null);
        boolean partial = (cl.getOpt("partial") != null);

        File[] schemaFiles = cl.filesEndingWith(".xsd");
        File[] jarFiles = cl.filesEndingWith(".jar");

        // step 1: load all the files
        List sdocs = new ArrayList();
        for (int i = 0; i < schemaFiles.length; i++)
        {
            try
            {
                sdocs.add(
                    SchemaDocument.Factory.parse(
                        schemaFiles[i], (new XmlOptions()).setLoadLineNumbers()));
            }
            catch (Exception e)
            {
                System.err.println( schemaFiles[i] + " not loadable: " + e );
            }
        }


        XmlObject[] schemas = (XmlObject[])sdocs.toArray(new XmlObject[0]);

        // step 2: compile all the schemas
        SchemaTypeLoader linkTo = null;
        SchemaTypeSystem typeSystem;
        Collection compErrors = new ArrayList();
        XmlOptions schemaOptions = new XmlOptions();
        schemaOptions.setErrorListener(compErrors);
        schemaOptions.setCompileDownloadUrls();
        if (nopvr)
            schemaOptions.setCompileNoPvrRule();
        if (noupa)
            schemaOptions.setCompileNoUpaRule();
        if (partial)
            schemaOptions.setCompilePartialTypesystem();

        if (jarFiles != null && jarFiles.length > 0)
            linkTo = XmlBeans.typeLoaderForResource(XmlBeans.resourceLoaderForPath(jarFiles));

        try
        {
            typeSystem = XmlBeans.compileXsd(schemas, linkTo, schemaOptions);
        }
        catch (XmlException e)
        {
            System.out.println("Schema invalid:" + (partial ? " couldn't recover from errors" : ""));
            if (compErrors.isEmpty())
                System.out.println(e.getMessage());
            else for (Iterator i = compErrors.iterator(); i.hasNext(); )
                System.out.println(i.next());
            return;
        }

        // step 2.5: recovered from errors, print out errors
        if (partial && !compErrors.isEmpty())
        {
            System.out.println("Schema invalid: partial schema type system recovered");
            for (Iterator i = compErrors.iterator(); i.hasNext(); )
                System.out.println(i.next());
        }

        // step 3: go through all the types, and note their base types and namespaces
        Map prefixes = new HashMap();
        prefixes.put("http://www.w3.org/XML/1998/namespace", "xml");
        prefixes.put("http://www.w3.org/2001/XMLSchema", "xs");
        System.out.println("xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"");

        // This will be a map of (base SchemaType -> Collection of directly dervied types)
        Map childTypes = new HashMap();

        // breadthfirst traversal of the type containment tree
        List allSeenTypes = new ArrayList();
        allSeenTypes.addAll(Arrays.asList(typeSystem.documentTypes()));
        allSeenTypes.addAll(Arrays.asList(typeSystem.attributeTypes()));
        allSeenTypes.addAll(Arrays.asList(typeSystem.globalTypes()));

        for (int i = 0; i < allSeenTypes.size(); i++)
        {
            SchemaType sType = (SchemaType)allSeenTypes.get(i);

            // recurse through nested anonymous types as well
            if (!noanon)
                allSeenTypes.addAll(Arrays.asList(sType.getAnonymousTypes()));

            // we're not interested in document types, attribute types, or chasing the base type of anyType
            if (sType.isDocumentType() || sType.isAttributeType() || sType == XmlObject.type)
                continue;

            // assign a prefix to the namespace of this type if needed
            noteNamespace(prefixes, sType);

            // enter this type in the list of children of its base type
            Collection children = (Collection)childTypes.get(sType.getBaseType());
            if (children == null)
            {
                children = new ArrayList();
                childTypes.put(sType.getBaseType(), children);

                // the first time a builtin type is seen, add it too (to get a complete tree up to anyType)
                if (sType.getBaseType().isBuiltinType())
                    allSeenTypes.add(sType.getBaseType());
            }
            children.add(sType);
        }

        // step 4: print the tree, starting from xs:anyType (i.e., XmlObject.type)
        List typesToPrint = new ArrayList();
        typesToPrint.add(XmlObject.type);
        StringBuilder spaces = new StringBuilder();
        while (!typesToPrint.isEmpty())
        {
            SchemaType sType = (SchemaType)typesToPrint.remove(typesToPrint.size() - 1);
            if (sType == null)
                spaces.setLength(Math.max(0, spaces.length() - 2));
            else
            {
                System.out.println(spaces + "+-" + QNameHelper.readable(sType, prefixes) + notes(sType));
                Collection children = (Collection)childTypes.get(sType);
                if (children != null && children.size() > 0)
                {
                    spaces.append(typesToPrint.size() == 0 || typesToPrint.get(typesToPrint.size() - 1) == null ? "  " : "| ");
                    typesToPrint.add(null);
                    typesToPrint.addAll(children);
                }
            }
        }
    }

    private static String notes(SchemaType sType)
    {
        if (sType.isBuiltinType())
            return " (builtin)";

        if (sType.isSimpleType())
        {
            switch (sType.getSimpleVariety())
            {
                case SchemaType.LIST:
                    return " (list)";
                case SchemaType.UNION:
                    return " (union)";
                default:
                    if (sType.getEnumerationValues() != null)
                        return " (enumeration)";
                    return "";
            }
        }

        switch (sType.getContentType())
        {
            case SchemaType.MIXED_CONTENT:
                return " (mixed)";
            case SchemaType.SIMPLE_CONTENT:
                return " (complex)";
            default:
                return "";
        }
    }

    private static void noteNamespace(Map prefixes, SchemaType sType)
    {
        String namespace = QNameHelper.namespace(sType);
        if (namespace.equals("") || prefixes.containsKey(namespace))
            return;

        String base = QNameHelper.suggestPrefix(namespace);
        String result = base;
        for (int n = 0; prefixes.containsValue(result); n += 1)
        {
            result = base + n;
        }

        prefixes.put(namespace, result);
        System.out.println("xmlns:" + result + "=\"" + namespace + "\"");
    }
}
