/* XMLSchemaBuilder.java --
   Copyright (C) 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.xml.validation.xmlschema;

import java.util.LinkedHashSet;
import java.util.Set;
import java.util.StringTokenizer;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import org.relaxng.datatype.DatatypeException;
import org.relaxng.datatype.DatatypeLibrary;
import org.relaxng.datatype.helpers.DatatypeLibraryLoader;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import gnu.xml.validation.datatype.Annotation;
import gnu.xml.validation.datatype.SimpleType;
import gnu.xml.validation.datatype.Type;

/**
 * Parses an XML Schema DOM tree, constructing a compiled internal
 * representation.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
class XMLSchemaBuilder
{

  XMLSchema schema;
  final DatatypeLibrary typeLibrary;

  XMLSchemaBuilder()
  {
    final String ns = XMLConstants.W3C_XML_SCHEMA_NS_URI;
    typeLibrary = new DatatypeLibraryLoader().createDatatypeLibrary(ns);
  }

  void parseSchema(Node node)
    throws DatatypeException
  {
    String uri = node.getNamespaceURI();
    String name = node.getLocalName();
    if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
        node.getNodeType() == Node.ELEMENT_NODE)
      {
        if ("schema".equals(name))
          {
            NamedNodeMap attrs = node.getAttributes();
            String targetNamespace = getAttribute(attrs, "targetNamespace");
            String version = getAttribute(attrs, "version");
            String fd = getAttribute(attrs, "finalDefault");
            int finalDefault = parseFullDerivationSet(fd);
            String bd = getAttribute(attrs, "blockDefault");
            int blockDefault = parseBlockSet(bd);
            String afd = getAttribute(attrs, "attributeFormDefault");
            boolean attributeFormQualified = "qualified".equals(afd);
            String efd = getAttribute(attrs, "elementFormDefault");
            boolean elementFormQualified = "qualified".equals(efd);
            schema = new XMLSchema(targetNamespace, version,
                                   finalDefault, blockDefault,
                                   attributeFormQualified,
                                   elementFormQualified);
            for (Node child = node.getFirstChild(); child != null;
                 child = child.getNextSibling())
              {
                parseTopLevelElement(child);
              }
            return;
          }
      }
    // TODO throw schema exception
  }

  void parseTopLevelElement(Node node)
    throws DatatypeException
  {
    String uri = node.getNamespaceURI();
    String name = node.getLocalName();
    if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
        node.getNodeType() == Node.ELEMENT_NODE)
      {
        if ("element".equals(name))
          {
            ElementDeclaration ed =
              (ElementDeclaration) parseElement(node, null);
            schema.elementDeclarations.put(ed.name, ed);
            // TODO
          }
        else if ("attribute".equals(name))
          {
            AttributeDeclaration ad =
              (AttributeDeclaration) parseAttribute(node, true);
            schema.attributeDeclarations.put(ad.name, ad);
            // TODO
          }
        else if ("type".equals(name))
          {
            // TODO
          }
        else if ("group".equals(name))
          {
            // TODO
          }
        else if ("attributeGroup".equals(name))
          {
            // TODO
          }
        else if ("notation".equals(name))
          {
            // TODO
          }
        else if ("identityConstraint".equals(name))
          {
            // TODO
          }
      }
    // TODO throw schema exception
  }

  Object parseAttribute(Node node, boolean scope)
    throws DatatypeException
  {
    NamedNodeMap attrs = node.getAttributes();
    String def = getAttribute(attrs, "default");
    String fixed = getAttribute(attrs, "fixed");
    int constraintType = AttributeDeclaration.NONE;
    String constraintValue = null;
    if (def != null)
      {
        constraintType = AttributeDeclaration.DEFAULT;
        constraintValue = def;
      }
    else if (fixed != null)
      {
        constraintType = AttributeDeclaration.FIXED;
        constraintValue = fixed;
      }
    // TODO form = (qualified | unqualified)
    String attrName = getAttribute(attrs, "name");
    String attrNamespace = getAttribute(attrs, "targetNamespace");
    String ref = getAttribute(attrs, "ref");
    String use = getAttribute(attrs, "use");
    String type = getAttribute(attrs, "type");
    SimpleType datatype = (type == null) ? null :
      parseSimpleType(asQName(type, node));
    Annotation annotation = null;
    for (Node child = node.getFirstChild(); child != null;
         child = child.getNextSibling())
      {
        String uri = child.getNamespaceURI();
        String name = child.getLocalName();
        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
            child.getNodeType() == Node.ELEMENT_NODE)
          {
            if ("annotation".equals(name))
              {
                annotation = parseAnnotation(child);
              }
            else if ("simpleType".equals(name))
              {
                datatype = parseSimpleType(child);
              }
            else
              {
                // TODO throw schema exception
              }
          }
      }
    if (scope)
      {
        return new AttributeDeclaration(scope,
                                        constraintType,
                                        constraintValue,
                                        new QName(attrNamespace, attrName),
                                        datatype,
                                        annotation);
      }
    else
      {
        boolean required = "required".equals(use);
        // TODO ref
        AttributeDeclaration decl = (ref == null) ?
              new AttributeDeclaration(scope,
                                       AttributeDeclaration.NONE,
                                       null,
                                       new QName(attrNamespace, attrName),
                                       datatype,
                                       annotation) :
              /*schema.getAttributeDeclaration(ref)*/ null;
        return new AttributeUse(required,
                                constraintType,
                                constraintValue,
                                decl);
      }
  }

  int parseFullDerivationSet(String value)
  {
    int ret = XMLSchema.FINAL_NONE;
    if ("#all".equals(value))
      {
        ret = XMLSchema.FINAL_ALL;
      }
    else
      {
        StringTokenizer st = new StringTokenizer(value, " ");
        while (st.hasMoreTokens())
          {
            String token = st.nextToken();
            if ("extension".equals(token))
              {
                ret |= XMLSchema.FINAL_EXTENSION;
              }
            else if ("restriction".equals(token))
              {
                ret |= XMLSchema.FINAL_RESTRICTION;
              }
            else if ("list".equals(token))
              {
                ret |= XMLSchema.FINAL_LIST;
              }
            else if ("union".equals(token))
              {
                ret |= XMLSchema.FINAL_UNION;
              }
          }
      }
    return ret;
  }

  int parseSimpleTypeDerivationSet(String value)
  {
    int ret = XMLSchema.FINAL_NONE;
    if ("#all".equals(value))
      {
        ret = XMLSchema.FINAL_LIST |
          XMLSchema.FINAL_UNION |
          XMLSchema.FINAL_RESTRICTION;
      }
    else
      {
        StringTokenizer st = new StringTokenizer(value, " ");
        while (st.hasMoreTokens())
          {
            String token = st.nextToken();
            if ("list".equals(token))
              {
                ret |= XMLSchema.FINAL_LIST;
              }
            else if ("union".equals(token))
              {
                ret |= XMLSchema.FINAL_UNION;
              }
            else if ("restriction".equals(token))
              {
                ret |= XMLSchema.FINAL_RESTRICTION;
              }
          }
      }
    return ret;
  }

  int parseComplexTypeDerivationSet(String value)
  {
    int ret = XMLSchema.FINAL_NONE;
    if ("#all".equals(value))
      {
        ret = XMLSchema.FINAL_EXTENSION | XMLSchema.FINAL_RESTRICTION;
      }
    else
      {
        StringTokenizer st = new StringTokenizer(value, " ");
        while (st.hasMoreTokens())
          {
            String token = st.nextToken();
            if ("extension".equals(token))
              {
                ret |= XMLSchema.FINAL_EXTENSION;
              }
            else if ("restriction".equals(token))
              {
                ret |= XMLSchema.FINAL_RESTRICTION;
              }
          }
      }
    return ret;
  }

  int parseBlockSet(String value)
  {
    int ret = XMLSchema.BLOCK_NONE;
    if ("#all".equals(value))
      {
        ret = XMLSchema.BLOCK_ALL;
      }
    else
      {
        StringTokenizer st = new StringTokenizer(value, " ");
        while (st.hasMoreTokens())
          {
            String token = st.nextToken();
            if ("extension".equals(token))
              {
                ret |= XMLSchema.BLOCK_EXTENSION;
              }
            else if ("restriction".equals(token))
              {
                ret |= XMLSchema.BLOCK_RESTRICTION;
              }
            else if ("substitution".equals(token))
              {
                ret |= XMLSchema.BLOCK_SUBSTITUTION;
              }
          }
      }
    return ret;
  }

  int parseComplexTypeBlockSet(String value)
  {
    int ret = XMLSchema.BLOCK_NONE;
    if ("#all".equals(value))
      {
        ret = XMLSchema.BLOCK_EXTENSION | XMLSchema.BLOCK_RESTRICTION;
      }
    else
      {
        StringTokenizer st = new StringTokenizer(value, " ");
        while (st.hasMoreTokens())
          {
            String token = st.nextToken();
            if ("extension".equals(token))
              {
                ret |= XMLSchema.BLOCK_EXTENSION;
              }
            else if ("restriction".equals(token))
              {
                ret |= XMLSchema.BLOCK_RESTRICTION;
              }
          }
      }
    return ret;
  }

  Object parseElement(Node node, ElementDeclaration parent)
    throws DatatypeException
  {
    NamedNodeMap attrs = node.getAttributes();
    Integer minOccurs = null;
    Integer maxOccurs = null;
    Node parentNode = node.getParentNode();
    boolean notTopLevel = !"schema".equals(parentNode.getLocalName());
    if (notTopLevel)
      {
        String ref = getAttribute(attrs, "ref");
        if (ref != null)
          {
            minOccurs = getOccurrence(getAttribute(attrs, "minOccurs"));
            maxOccurs = getOccurrence(getAttribute(attrs, "maxOccurs"));
            // TODO resolve top-level element declaration
            ElementDeclaration ad = null;
            return new Particle(minOccurs, maxOccurs, ad);
          }
      }
    String elementName = getAttribute(attrs, "name");
    String elementNamespace = getAttribute(attrs, "targetNamespace");
    String type = getAttribute(attrs, "type");
    Type datatype = (type != null) ?
      parseSimpleType(asQName(type, node)) : null;
    int scope = (parent == null) ?
      XMLSchema.GLOBAL :
      XMLSchema.LOCAL;
    String def = getAttribute(attrs, "default");
    String fixed = getAttribute(attrs, "fixed");
    int constraintType = AttributeDeclaration.NONE;
    String constraintValue = null;
    if (def != null)
      {
        constraintType = AttributeDeclaration.DEFAULT;
        constraintValue = def;
      }
    else if (fixed != null)
      {
        constraintType = AttributeDeclaration.FIXED;
        constraintValue = fixed;
      }
    String sg = getAttribute(attrs, "substitutionGroup");
    QName substitutionGroup = QName.valueOf(sg);
    String sgPrefix = substitutionGroup.getPrefix();
    if (sgPrefix != null && !"".equals(sgPrefix))
      {
        String sgName = substitutionGroup.getLocalPart();
        String sgNamespace = node.lookupNamespaceURI(sgPrefix);
        substitutionGroup = new QName(sgNamespace, sgName);
      }

    String block = getAttribute(attrs, "block");
    int substitutionGroupExclusions = (block == null) ?
      schema.blockDefault :
      parseBlockSet(block);
    String final_ = getAttribute(attrs, "final");
    int disallowedSubstitutions = (final_ == null) ?
      schema.finalDefault :
      parseFullDerivationSet(final_);

    boolean nillable = "true".equals(getAttribute(attrs, "nillable"));
    boolean isAbstract = "true".equals(getAttribute(attrs, "abstract"));

    if (notTopLevel)
      {
        minOccurs = getOccurrence(getAttribute(attrs, "minOccurs"));
        maxOccurs = getOccurrence(getAttribute(attrs, "maxOccurs"));
        String form = getAttribute(attrs, "form");
        if (form != null)
          {
            if ("qualified".equals(form))
              {
                elementNamespace = schema.targetNamespace;
              }
          }
        else if (schema.elementFormQualified)
          {
            elementNamespace = schema.targetNamespace;
          }
      }
    ElementDeclaration ed =
      new ElementDeclaration(new QName(elementNamespace, elementName),
                             datatype,
                             scope, parent,
                             constraintType, constraintValue,
                             nillable,
                             substitutionGroup,
                             substitutionGroupExclusions,
                             disallowedSubstitutions,
                             isAbstract);

    for (Node child = node.getFirstChild(); child != null;
         child = child.getNextSibling())
      {
        String uri = child.getNamespaceURI();
        String name = child.getLocalName();
        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
            child.getNodeType() == Node.ELEMENT_NODE)
          {
            if ("annotation".equals(name))
              {
                ed.annotation = parseAnnotation(child);
              }
            else if ("simpleType".equals(name) && datatype == null)
              {
                ed.datatype = parseSimpleType(child);
              }
            else if ("complexType".equals(name) && datatype == null)
              {
                ed.datatype = parseComplexType(child, ed);
              }
            else
              {
                // throw schema exception
              }
          }
      }

    if (notTopLevel)
      {
        return new Particle(minOccurs, maxOccurs, ed);
      }
    else
      {
        return ed;
      }
  }

  Integer getOccurrence(String value)
  {
    if (value == null)
      {
        return new Integer(1);
      }
    else if ("unbounded".equals(value))
      {
        return null;
      }
    else
      {
        return new Integer(value);
      }
  }

  SimpleType parseSimpleType(QName typeName)
    throws DatatypeException
  {
    SimpleType type = (SimpleType) schema.types.get(typeName);
    if (!XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(typeName.getNamespaceURI()))
      return null;
    String localName = typeName.getLocalPart();
    return (SimpleType) typeLibrary.createDatatype(localName);
  }

  SimpleType parseSimpleType(Node simpleType)
    throws DatatypeException
  {
    NamedNodeMap attrs = simpleType.getAttributes();
    String typeFinal = getAttribute(attrs, "final");
    if (typeFinal == null)
      {
        Node schema = simpleType.getParentNode();
        while (schema != null && !"schema".equals(schema.getLocalName()))
          {
            schema = schema.getParentNode();
          }
        if (schema != null)
          {
            NamedNodeMap schemaAttrs = schema.getAttributes();
            typeFinal = getAttribute(schemaAttrs, "finalDefault");
          }
      }
    int typeFinality = parseSimpleTypeDerivationSet(typeFinal);
    QName typeName = asQName(getAttribute(attrs, "name"), simpleType);
    int variety = 0;
    Set facets = new LinkedHashSet();
    int fundamentalFacets = 0; // TODO
    SimpleType baseType = null; // TODO
    Annotation annotation = null;
    // TODO use DatatypeBuilder
    for (Node child = simpleType.getFirstChild(); child != null;
         child = child.getNextSibling())
      {
        String uri = child.getNamespaceURI();
        String name = child.getLocalName();
        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
            child.getNodeType() == Node.ELEMENT_NODE)
          {
            if ("annotation".equals(name))
              {
                annotation = parseAnnotation(child);
              }
            else if ("restriction".equals(name))
              {
                // TODO
              }
            else if ("list".equals(name))
              {
                variety = SimpleType.LIST;
                // TODO
              }
            else if ("union".equals(name))
              {
                variety = SimpleType.UNION;
                // TODO
              }
          }
      }
    return new SimpleType(typeName, variety, facets, fundamentalFacets,
                          baseType, annotation);
  }

  Type parseComplexType(Node complexType, ElementDeclaration parent)
    throws DatatypeException
  {
    NamedNodeMap attrs = complexType.getAttributes();
    QName typeName = asQName(getAttribute(attrs, "name"), complexType);
    boolean isAbstract = "true".equals(getAttribute(attrs, "abstract"));
    String block = getAttribute(attrs, "block");
    int prohibitedSubstitutions = (block == null) ?
      schema.blockDefault :
      parseComplexTypeBlockSet(block);
    String final_ = getAttribute(attrs, "final");
    int finality = (final_ == null) ?
      schema.finalDefault :
      parseComplexTypeDerivationSet(final_);
    ComplexType type = new ComplexType(typeName, isAbstract,
                                       prohibitedSubstitutions, finality);
    boolean mixed = "true".equals(getAttribute(attrs, "mixed"));
    for (Node child = complexType.getFirstChild(); child != null;
         child = child.getNextSibling())
      {
        String uri = child.getNamespaceURI();
        String name = child.getLocalName();
        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
            child.getNodeType() == Node.ELEMENT_NODE)
          {
            if ("simpleContent".equals(name))
              {
                parseSimpleContent(child, type);
              }
          }
      }
    if (mixed)
      {
        type.contentType = XMLSchema.CONTENT_MIXED;
      }
    return type;
  }

  void parseSimpleContent(Node simpleContent, ComplexType type)
    throws DatatypeException
  {
    for (Node child = simpleContent.getFirstChild(); child != null;
         child = child.getNextSibling())
      {
        String uri = child.getNamespaceURI();
        String name = child.getLocalName();
        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
            child.getNodeType() == Node.ELEMENT_NODE)
          {
            if ("annotation".equals(name))
              {
                type.annotations.add(parseAnnotation(child));
              }
            else if ("restriction".equals(name))
              {
                type.derivationMethod = XMLSchema.FINAL_RESTRICTION;
                parseRestriction(child, type);
              }
            else if ("extension".equals(name))
              {
                type.derivationMethod = XMLSchema.FINAL_EXTENSION;
                parseExtension(child, type);
              }
          }
      }
  }

  void parseRestriction(Node restriction, ComplexType type)
    throws DatatypeException
  {
    NamedNodeMap attrs = restriction.getAttributes();
    String base = getAttribute(attrs, "base");
    QName baseType = asQName(base, restriction);
    SimpleType simpleType = null;
    for (Node child = restriction.getFirstChild(); child != null;
         child = child.getNextSibling())
      {
        String uri = child.getNamespaceURI();
        String name = child.getLocalName();
        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
            child.getNodeType() == Node.ELEMENT_NODE)
          {
            if ("annotation".equals(name))
              {
                type.annotations.add(parseAnnotation(child));
              }
            else if ("simpleType".equals(name))
              {
                type.contentType = XMLSchema.CONTENT_SIMPLE;
                simpleType = parseSimpleType(child);
              }
            else if ("minExclusive".equals(name))
              {
              }
            else if ("minInclusive".equals(name))
              {
              }
            else if ("maxExclusive".equals(name))
              {
              }
            else if ("maxInclusive".equals(name))
              {
              }
            else if ("totalDigits".equals(name))
              {
              }
            else if ("fractionDigits".equals(name))
              {
              }
            else if ("length".equals(name))
              {
              }
            else if ("minLength".equals(name))
              {
              }
            else if ("maxLength".equals(name))
              {
              }
            else if ("enumeration".equals(name))
              {
              }
            else if ("whiteSpace".equals(name))
              {
              }
            else if ("pattern".equals(name))
              {
              }
            else if ("attribute".equals(name))
              {
                AttributeUse use =
                  (AttributeUse) parseAttribute(child, false);
                schema.attributeDeclarations.put(use.declaration.name,
                                                 use.declaration);
                type.attributeUses.add(use);
              }
            else if ("attributeGroup".equals(name))
              {
                NamedNodeMap agAttrs = child.getAttributes();
                String ref = getAttribute(agAttrs, "ref");
                QName ag = asQName(ref, child);
                type.attributeUses.add(ag);
              }
            else if ("anyAttribute".equals(name))
              {
                type.attributeWildcard = parseAnyAttribute(child);
              }
          }
      }
  }

  void parseExtension(Node extension, ComplexType type)
    throws DatatypeException
  {
    NamedNodeMap attrs = extension.getAttributes();
    String base = getAttribute(attrs, "base");
    QName baseType = asQName(base, extension);
    for (Node child = extension.getFirstChild(); child != null;
         child = child.getNextSibling())
      {
        String uri = child.getNamespaceURI();
        String name = child.getLocalName();
        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
            child.getNodeType() == Node.ELEMENT_NODE)
          {
            if ("annotation".equals(name))
              {
                type.annotations.add(parseAnnotation(child));
              }
            else if ("attribute".equals(name))
              {
                AttributeUse use =
                  (AttributeUse) parseAttribute(child, false);
                schema.attributeDeclarations.put(use.declaration.name,
                                                 use.declaration);
                type.attributeUses.add(use);
              }
            else if ("attributeGroup".equals(name))
              {
                NamedNodeMap agAttrs = child.getAttributes();
                String ref = getAttribute(agAttrs, "ref");
                QName ag = asQName(ref, child);
                type.attributeUses.add(ag);
              }
            else if ("anyAttribute".equals(name))
              {
                type.attributeWildcard = parseAnyAttribute(child);
              }
          }
      }
  }

  AnyAttribute parseAnyAttribute(Node node)
  {
    NamedNodeMap attrs = node.getAttributes();
    String namespace = getAttribute(attrs, "namespace");
    String pc = getAttribute(attrs, "processContents");
    int processContents = AnyAttribute.STRICT;
    if ("lax".equals(pc))
      {
        processContents = AnyAttribute.LAX;
      }
    else if ("skip".equals(pc))
      {
        processContents = AnyAttribute.SKIP;
      }
    AnyAttribute ret = new AnyAttribute(namespace, processContents);
    for (Node child = node.getFirstChild(); child != null;
         child = child.getNextSibling())
      {
        String uri = child.getNamespaceURI();
        String name = child.getLocalName();
        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
            child.getNodeType() == Node.ELEMENT_NODE)
          {
            if ("annotation".equals(name))
              {
                ret.annotation = parseAnnotation(child);
              }
          }
      }
    return ret;
  }

  Annotation parseAnnotation(Node node)
  {
    // TODO
    return null;
  }

  private static String getAttribute(NamedNodeMap attrs, String name)
  {
    Node attr = attrs.getNamedItem(name);
    return (attr == null) ? null : attr.getNodeValue();
  }

  private static QName asQName(String text, Node resolver)
  {
    QName name = QName.valueOf(text);
    String prefix = name.getPrefix();
    if (prefix != null && prefix.length() > 0)
      {
        String uri = resolver.lookupNamespaceURI(prefix);
        name = new QName(uri, name.getLocalPart());
      }
    return name;
  }

}
