/*
 * 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.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.DefaultHandler2;

import java.io.IOException;
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) throws SAXException, IOException {
    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);
  }
}