// Copyright 2016 The Bazel Authors. All rights reserved.
//
// 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.devtools.build.android;

import com.android.SdkConstants;
import com.android.resources.ResourceType;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.android.ParsedAndroidData.KeyValueConsumer;
import com.google.devtools.build.android.proto.SerializeFormat;
import com.google.devtools.build.android.xml.AttrXmlResourceValue;
import com.google.devtools.build.android.xml.IdXmlResourceValue;
import com.google.devtools.build.android.xml.Namespaces;
import com.google.devtools.build.android.xml.PluralXmlResourceValue;
import com.google.devtools.build.android.xml.PublicXmlResourceValue;
import com.google.devtools.build.android.xml.SimpleXmlResourceValue;
import com.google.devtools.build.android.xml.StyleXmlResourceValue;
import com.google.devtools.build.android.xml.StyleableXmlResourceValue;
import com.google.protobuf.CodedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

/**
 * {@link XmlResourceValues} provides methods for getting {@link XmlResourceValue} derived classes.
 *
 * <p>Acts a static factory class containing the general xml parsing logic for resources that are
 * declared inside the &lt;resources&gt; tag.
 */
public class XmlResourceValues {

  private static final Logger logger = Logger.getLogger(XmlResourceValues.class.getCanonicalName());

  private static final QName TAG_EAT_COMMENT = QName.valueOf("eat-comment");
  private static final QName TAG_PLURALS = QName.valueOf("plurals");
  private static final QName ATTR_QUANTITY = QName.valueOf("quantity");
  private static final QName TAG_ATTR = QName.valueOf("attr");
  private static final QName TAG_DECLARE_STYLEABLE = QName.valueOf("declare-styleable");
  private static final QName TAG_ITEM = QName.valueOf("item");
  private static final QName TAG_STYLE = QName.valueOf("style");
  private static final QName TAG_SKIP = QName.valueOf("skip");
  private static final QName TAG_RESOURCES = QName.valueOf("resources");
  private static final QName ATTR_FORMAT = QName.valueOf("format");
  private static final QName ATTR_NAME = QName.valueOf("name");
  private static final QName ATTR_VALUE = QName.valueOf("value");
  private static final QName ATTR_PARENT = QName.valueOf("parent");
  private static final QName ATTR_TYPE = QName.valueOf("type");

  private static final XMLOutputFactory XML_OUTPUT_FACTORY = XMLOutputFactory.newInstance();

  private static XMLInputFactory inputFactoryInstance = null;

  public static XMLInputFactory getXmlInputFactory() {
    if (inputFactoryInstance == null) {
      inputFactoryInstance = XMLInputFactory.newInstance();
      inputFactoryInstance.setProperty(
          "http://java.sun.com/xml/stream/properties/report-cdata-event", Boolean.TRUE);
    }
    return inputFactoryInstance;
  }

  static XmlResourceValue parsePlurals(
      XMLEventReader eventReader, StartElement start, Namespaces.Collector namespacesCollector)
      throws XMLStreamException {
    ImmutableMap.Builder<String, String> values = ImmutableMap.builder();
    namespacesCollector.collectFrom(start);
    for (XMLEvent element = nextTag(eventReader);
        !isEndTag(element, TAG_PLURALS);
        element = nextTag(eventReader)) {
      if (isItem(element)) {
        if (!element.isStartElement()) {
          throw new XMLStreamException(
              String.format("Expected start element %s", element), element.getLocation());
        }
        String contents =
            readContentsAsString(
                eventReader, element.asStartElement().getName(), namespacesCollector);
        values.put(
            getElementAttributeByName(element.asStartElement(), ATTR_QUANTITY),
            contents == null ? "" : contents);
      }
    }
    return PluralXmlResourceValue.createWithAttributesAndValues(
        ImmutableMap.copyOf(parseTagAttributes(start)), values.build());
  }

  static XmlResourceValue parseStyle(XMLEventReader eventReader, StartElement start)
      throws XMLStreamException {
    Map<String, String> values = new LinkedHashMap<>();
    for (XMLEvent element = nextTag(eventReader);
        !isEndTag(element, TAG_STYLE);
        element = nextTag(eventReader)) {
      if (isItem(element)) {
        values.put(getElementName(element.asStartElement()), eventReader.getElementText());
      }
    }
    // Parents can be declared as:
    //   ?style/parent
    //   @style/parent
    //   <Parent>
    // And, in the resource name <parent>.<resource name>
    // Here, we take a garbage in, garbage out approach and just read the xml value raw.
    return StyleXmlResourceValue.of(getElementAttributeByName(start, ATTR_PARENT), values);
  }

  static void parseDeclareStyleable(
      FullyQualifiedName.Factory fqnFactory,
      Path path,
      KeyValueConsumer<DataKey, DataResource> overwritingConsumer,
      KeyValueConsumer<DataKey, DataResource> combiningConsumer,
      XMLEventReader eventReader,
      StartElement start)
      throws XMLStreamException {
    Map<FullyQualifiedName, Boolean> members = new LinkedHashMap<>();
    for (XMLEvent element = nextTag(eventReader);
        !isEndTag(element, TAG_DECLARE_STYLEABLE);
        element = nextTag(eventReader)) {
      if (isStartTag(element, TAG_ATTR)) {
        StartElement attr = element.asStartElement();
        FullyQualifiedName attrName = fqnFactory.create(ResourceType.ATTR, getElementName(attr));
        // If there is format and the next tag is a starting tag, treat it as an attr definition.
        // Without those, it will be an attr reference.
        if (XmlResourceValues.getElementAttributeByName(attr, ATTR_FORMAT) != null
            || (XmlResourceValues.peekNextTag(eventReader) != null
                && XmlResourceValues.peekNextTag(eventReader).isStartElement())) {
          overwritingConsumer.accept(
              attrName, DataResourceXml.createWithNoNamespace(path, parseAttr(eventReader, attr)));
          members.put(attrName, Boolean.TRUE);
        } else {
          members.put(attrName, Boolean.FALSE);
        }
      }
    }
    combiningConsumer.accept(
        fqnFactory.create(ResourceType.STYLEABLE, getElementName(start)),
        DataResourceXml.createWithNoNamespace(path, StyleableXmlResourceValue.of(members)));
  }

  static XmlResourceValue parseAttr(XMLEventReader eventReader, StartElement start)
      throws XMLStreamException {
    XmlResourceValue value =
        AttrXmlResourceValue.from(
            start, getElementAttributeByName(start, ATTR_FORMAT), eventReader);
    return value;
  }

  static XmlResourceValue parseId(
      XMLEventReader eventReader, StartElement start, Namespaces.Collector namespacesCollector)
      throws XMLStreamException {
    try {
      if (XmlResourceValues.isEndTag(eventReader.peek(), start.getName())) {
        return IdXmlResourceValue.of();
      } else {
        return IdXmlResourceValue.of(
            readContentsAsString(
                eventReader, start.getName(), namespacesCollector.collectFrom(start)));
      }
    } catch (IllegalArgumentException e) {
      throw new XMLStreamException(e);
    }
  }

  static XmlResourceValue parseSimple(
      XMLEventReader eventReader,
      ResourceType resourceType,
      StartElement start,
      Namespaces.Collector namespacesCollector)
      throws XMLStreamException {
    String contents;
    namespacesCollector.collectFrom(start);
    // Check that the element is unary. If it is, the contents is null
    if (isEndTag(eventReader.peek(), start.getName())) {
      contents = null;
    } else {
      contents = readContentsAsString(eventReader, start.getName(), namespacesCollector);
    }
    return SimpleXmlResourceValue.of(
        start.getName().equals(TAG_ITEM)
            ? SimpleXmlResourceValue.Type.ITEM
            : SimpleXmlResourceValue.Type.from(resourceType),
        ImmutableMap.copyOf(parseTagAttributes(start)),
        contents);
  }

  static XmlResourceValue parsePublic(
      XMLEventReader eventReader, StartElement start, Namespaces.Collector namespacesCollector)
      throws XMLStreamException {
    namespacesCollector.collectFrom(start);
    // The tag should be unary.
    if (!isEndTag(eventReader.peek(), start.getName())) {
      throw new XMLStreamException(
          String.format("<public> tag should be unary %s", start), start.getLocation());
    }
    // The tag should have a valid type attribute, and optionally an id attribute.
    ImmutableMap<String, String> attributes = ImmutableMap.copyOf(parseTagAttributes(start));
    String typeAttr = attributes.get(SdkConstants.ATTR_TYPE);
    ResourceType type;
    if (typeAttr != null) {
      type = ResourceType.getEnum(typeAttr);
      if (type == null || type == ResourceType.PUBLIC) {
        throw new XMLStreamException(
            String.format("<public> tag has invalid type attribute %s", start),
            start.getLocation());
      }
    } else {
      throw new XMLStreamException(
          String.format("<public> tag missing type attribute %s", start), start.getLocation());
    }
    String idValueAttr = attributes.get(SdkConstants.ATTR_ID);
    Optional<Integer> id = Optional.absent();
    if (idValueAttr != null) {
      try {
        id = Optional.of(Integer.decode(idValueAttr));
      } catch (NumberFormatException e) {
        throw new XMLStreamException(
            String.format("<public> has invalid id number %s", start), start.getLocation());
      }
    }
    if (attributes.size() > 2) {
      throw new XMLStreamException(
          String.format("<public> has unexpected attributes %s", start), start.getLocation());
    }
    return PublicXmlResourceValue.create(type, id);
  }

  public static Map<String, String> parseTagAttributes(StartElement start) {
    // Using a map to deduplicate xmlns declarations on the attributes.
    Map<String, String> attributeMap = new LinkedHashMap<>();
    Iterator<Attribute> attributes = iterateAttributesFrom(start);
    while (attributes.hasNext()) {
      Attribute attribute = attributes.next();
      QName name = attribute.getName();
      // Name used as the resource key, so skip it here.
      if (ATTR_NAME.equals(name)) {
        continue;
      }
      String value = escapeXmlValues(attribute.getValue()).replace("\"", "&quot;");
      if (!name.getNamespaceURI().isEmpty()) {
        attributeMap.put(name.getPrefix() + ":" + attribute.getName().getLocalPart(), value);
      } else {
        attributeMap.put(attribute.getName().getLocalPart(), value);
      }
      Iterator<Namespace> namespaces = iterateNamespacesFrom(start);
      while (namespaces.hasNext()) {
        Namespace namespace = namespaces.next();
        attributeMap.put("xmlns:" + namespace.getPrefix(), namespace.getNamespaceURI());
      }
    }
    return attributeMap;
  }

  // TODO(corysmith): Replace this with real escaping system, preferably a performant high level xml
  // writing library. See AndroidDataWritingVisitor TODO.
  private static String escapeXmlValues(String data) {
    return data.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
  }

  /**
   * Reads the xml events as a string until finding a closing tag.
   *
   * @param eventReader The current xml stream.
   * @param startTag The name of the tag to close on.
   * @param namespacesCollector A builder for collecting namespaces.
   * @return A xml escaped string representation of the xml stream
   */
  @Nullable
  public static String readContentsAsString(
      XMLEventReader eventReader, QName startTag, Namespaces.Collector namespacesCollector)
      throws XMLStreamException {
    StringWriter contents = new StringWriter();
    XMLEventWriter writer = XML_OUTPUT_FACTORY.createXMLEventWriter(contents);
    while (!isEndTag(eventReader.peek(), startTag)) {
      XMLEvent xmlEvent = (XMLEvent) eventReader.next();
      if (xmlEvent.isStartElement()) {
        namespacesCollector.collectFrom(xmlEvent.asStartElement());
        writer.add(xmlEvent);
      } else {
        writer.add(xmlEvent);
      }
    }
    // Verify the end element.
    EndElement endElement = eventReader.nextEvent().asEndElement();
    Preconditions.checkArgument(endElement.getName().equals(startTag));
    return contents.toString();
  }

  @SuppressWarnings({
    "unchecked"
  }) // The interface returns Iterator, force casting based on documentation.
  public static Iterator<Attribute> iterateAttributesFrom(StartElement start) {
    return start.getAttributes();
  }

  @SuppressWarnings("unchecked")
  public static Iterator<Namespace> iterateNamespacesFrom(StartElement start) {
    return start.getNamespaces();
  }

  /* XML helper methods follow. */
  // TODO(corysmith): Move these to a wrapper class for XMLEventReader.

  @Nullable
  public static String getElementAttributeByName(StartElement element, QName name) {
    Attribute attribute = element.getAttributeByName(name);
    return attribute == null ? null : attribute.getValue();
  }

  public static String getElementValue(StartElement start) {
    return getElementAttributeByName(start, ATTR_VALUE);
  }

  public static String getElementName(StartElement start) {
    return getElementAttributeByName(start, ATTR_NAME);
  }

  public static String getElementType(StartElement start) {
    return getElementAttributeByName(start, ATTR_TYPE);
  }

  public static boolean isTag(XMLEvent event, QName subTagType) {
    if (event.isStartElement()) {
      return isStartTag(event, subTagType);
    }
    if (event.isEndElement()) {
      return isEndTag(event, subTagType);
    }
    return false;
  }

  public static boolean isItem(XMLEvent start) {
    return isTag(start, TAG_ITEM);
  }

  public static boolean isEndTag(XMLEvent event, QName subTagType) {
    if (event.isEndElement()) {
      return subTagType.equals(event.asEndElement().getName());
    }
    return false;
  }

  public static boolean isStartTag(XMLEvent event, QName subTagType) {
    if (event.isStartElement()) {
      return subTagType.equals(event.asStartElement().getName());
    }
    return false;
  }

  public static XMLEvent nextTag(XMLEventReader eventReader) throws XMLStreamException {
    while (eventReader.hasNext()
        && !(eventReader.peek().isEndElement() || eventReader.peek().isStartElement())) {
      XMLEvent nextEvent = eventReader.nextEvent();
      if (nextEvent.isCharacters() && !nextEvent.asCharacters().isIgnorableWhiteSpace()) {
        Characters characters = nextEvent.asCharacters();
        // TODO(corysmith): Turn into a warning with the Path is available to add to it.
        // This case is when unexpected characters are thrown into the xml. Best case, it's a
        // incorrect comment type...
        logger.fine(
            String.format(
                "Invalid characters [%s] found at %s",
                characters.getData(), characters.getLocation().getLineNumber()));
      }
    }
    return eventReader.nextEvent();
  }

  public static XMLEvent peekNextTag(XMLEventReader eventReader) throws XMLStreamException {
    while (eventReader.hasNext()
        && !(eventReader.peek().isEndElement() || eventReader.peek().isStartElement())) {
      eventReader.nextEvent();
    }
    return eventReader.peek();
  }

  @Nullable
  static StartElement findNextStart(XMLEventReader eventReader) throws XMLStreamException {
    while (eventReader.hasNext()) {
      XMLEvent event = eventReader.nextEvent();
      if (event.isStartElement()) {
        return event.asStartElement();
      }
    }
    return null;
  }

  static StartElement moveToResources(XMLEventReader eventReader) throws XMLStreamException {
    while (eventReader.hasNext()) {
      StartElement next = findNextStart(eventReader);
      if (next != null && next.getName().equals(TAG_RESOURCES)) {
        return next;
      }
    }
    return null;
  }

  public static SerializeFormat.DataValue.Builder newSerializableDataValueBuilder(int sourceId) {
    SerializeFormat.DataValue.Builder builder = SerializeFormat.DataValue.newBuilder();
    return builder.setSourceId(sourceId);
  }

  public static int serializeProtoDataValue(
      OutputStream output, SerializeFormat.DataValue.Builder builder) throws IOException {
    SerializeFormat.DataValue value = builder.build();
    value.writeDelimitedTo(output);
    return CodedOutputStream.computeUInt32SizeNoTag(value.getSerializedSize())
        + value.getSerializedSize();
  }

  public static boolean isEatComment(StartElement start) {
    return isTag(start, TAG_EAT_COMMENT);
  }

  public static boolean isSkip(StartElement start) {
    return isTag(start, TAG_SKIP);
  }
}
