/*
 * Copyright 2010 Google Inc.
 * 
 * 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 com.google.gwt.uibinder.rebind;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.dev.resource.ResourceOracle;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.DefaultHandler2;

import java.util.Stack;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

/**
 * Uses SAX events to construct a DOM Document. Each node in the Document will
 * have a {@link XMLElement.Location} object attached to that Node's user data
 * with the {@value XMLElement#LOCATION_KEY} key.
 */
class W3cDocumentBuilder extends DefaultHandler2 {
  private final Document document;
  private final Stack<Node> eltStack = new Stack<Node>();
  private Locator locator;
  private final TreeLogger logger;
  private final GwtResourceEntityResolver resolver;

  public W3cDocumentBuilder(TreeLogger logger, String pathBase,
      ResourceOracle resourceOracle) throws ParserConfigurationException {
    this.logger = logger;
    document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
    eltStack.push(document);
    resolver = new GwtResourceEntityResolver(resourceOracle, pathBase);
  }

  /**
   * Appends to the existing Text node, if possible.
   */
  @Override
  public void characters(char[] ch, int start, int length) {
    Node current = eltStack.peek();
    if (current.getChildNodes().getLength() == 1
        && current.getChildNodes().item(0).getNodeType() == Node.TEXT_NODE) {
      Text text = (Text) current.getChildNodes().item(0);
      text.appendData(new String(ch, start, length));
    } else {
      Text text = document.createTextNode(new String(ch, start, length));
      eltStack.peek().appendChild(text);
    }
  }

  @Override
  public void endElement(String uri, String localName, String qName) {
    Node elt = eltStack.pop();
    assert elt.getLocalName().equals(localName);
  }

  @Override
  public void error(SAXParseException exception) {
    logger.log(Type.ERROR, exception.getMessage());
    logger.log(Type.DEBUG, "SAXParseException", exception);
  }

  @Override
  public void fatalError(SAXParseException exception) {
    /*
     * Fatal errors seem to be no scarier than error errors, and simply happen
     * due to badly formed XML.
     */
    logger.log(Type.ERROR, exception.getMessage());
    logger.log(Type.DEBUG, "SAXParseException", exception);
  }

  public Document getDocument() {
    return document;
  }

  @Override
  public InputSource resolveEntity(String name, String publicId,
      String baseURI, String systemId) {
    return resolver.resolveEntity(publicId, systemId);
  }

  /**
   * This is the whole reason for this mess. We want to know where a given
   * element comes from.
   */
  @Override
  public void setDocumentLocator(Locator locator) {
    this.locator = locator;
  }

  @Override
  public void startElement(String uri, String localName, String qName,
      Attributes attributes) {
    Element elt = document.createElementNS(uri, qName);
    eltStack.peek().appendChild(elt);
    eltStack.push(elt);

    for (int i = 0, j = attributes.getLength(); i < j; i++) {
      elt.setAttributeNS(attributes.getURI(i), attributes.getQName(i),
          attributes.getValue(i));
    }

    XMLElement.Location location = new XMLElement.Location(
        locator.getSystemId(), locator.getLineNumber());
    elt.setUserData(XMLElement.LOCATION_KEY, location, null);
  }

  @Override
  public void warning(SAXParseException exception) {
    logger.log(Type.WARN, exception.getMessage());
    logger.log(Type.DEBUG, "SAXParseException", exception);
  }
}