// Copyright 2014 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.lib.query2.query.output;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.hash.HashFunction;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.DependencyFilter;
import com.google.devtools.build.lib.packages.EnvironmentGroup;
import com.google.devtools.build.lib.packages.InputFile;
import com.google.devtools.build.lib.packages.LabelPrinter;
import com.google.devtools.build.lib.packages.License;
import com.google.devtools.build.lib.packages.OutputFile;
import com.google.devtools.build.lib.packages.PackageGroup;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.query2.common.CommonQueryOptions;
import com.google.devtools.build.lib.query2.compat.FakeLoadTarget;
import com.google.devtools.build.lib.query2.engine.OutputFormatterCallback;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment;
import com.google.devtools.build.lib.query2.engine.SynchronizedDelegatingOutputFormatterCallback;
import com.google.devtools.build.lib.query2.engine.ThreadSafeOutputFormatterCallback;
import com.google.devtools.build.lib.query2.query.aspectresolvers.AspectResolver;
import java.io.OutputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * An output formatter that prints the result as XML.
 */
class XmlOutputFormatter extends AbstractUnorderedFormatter {

  private AspectResolver aspectResolver;
  private DependencyFilter dependencyFilter;
  private boolean packageGroupIncludesDoubleSlash;
  private boolean relativeLocations;
  private boolean displaySourceFileLocation;
  private QueryOptions queryOptions;

  @Override
  public String getName() {
    return "xml";
  }

  @Override
  public ThreadSafeOutputFormatterCallback<Target> createStreamCallback(
      OutputStream out, QueryOptions options, QueryEnvironment<?> env) {
    return new SynchronizedDelegatingOutputFormatterCallback<>(
        createPostFactoStreamCallback(out, options, env.getLabelPrinter()));
  }

  @Override
  public void setOptions(
      CommonQueryOptions options, AspectResolver aspectResolver, HashFunction hashFunction) {
    super.setOptions(options, aspectResolver, hashFunction);
    this.aspectResolver = aspectResolver;
    this.dependencyFilter = FormatUtils.getDependencyFilter(options);
    this.packageGroupIncludesDoubleSlash = options.incompatiblePackageGroupIncludesDoubleSlash;
    this.relativeLocations = options.relativeLocations;
    this.displaySourceFileLocation = options.displaySourceFileLocation;

    Preconditions.checkArgument(options instanceof QueryOptions);
    this.queryOptions = (QueryOptions) options;
  }

  @Override
  public OutputFormatterCallback<Target> createPostFactoStreamCallback(
      OutputStream out, QueryOptions options, LabelPrinter labelPrinter) {
    return new OutputFormatterCallback<Target>() {

      private Document doc;
      private Element queryElem;

      @Override
      public void start() {
        try {
          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
          doc = factory.newDocumentBuilder().newDocument();
        } catch (ParserConfigurationException e) {
          // This shouldn't be possible: all the configuration is hard-coded.
          throw new IllegalStateException("XML output failed", e);
        }
        doc.setXmlVersion("1.1");
        queryElem = doc.createElement("query");
        queryElem.setAttribute("version", "2");
        doc.appendChild(queryElem);
      }

      @Override
      public void processOutput(Iterable<Target> partialResult) throws InterruptedException {
        for (Target target : partialResult) {
          queryElem.appendChild(createTargetElement(doc, target, labelPrinter));
        }
      }

      @Override
      public void close(boolean failFast) {
        if (!failFast) {
          try {
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.transform(new DOMSource(doc), new StreamResult(out));
          } catch (TransformerFactoryConfigurationError | TransformerException e) {
            // This shouldn't be possible: all the configuration is hard-coded.
            throw new IllegalStateException("XML output failed", e);
          }
        }
      }
    };
  }

  /**
   * Creates and returns a new DOM tree for the specified build target.
   *
   * <p>XML structure: - element tag is &lt;source-file>, &lt;generated-file> or &lt;rule
   * class="cc_library">, following the terminology of {@link Target#getTargetKind()}. - 'name'
   * attribute is target's label. - 'location' attribute is consistent with output of --output
   * location. - rule attributes are represented in the DOM structure.
   */
  private Element createTargetElement(Document doc, Target target, LabelPrinter labelPrinter)
      throws InterruptedException {
    Element elem;
    if (target instanceof Rule) {
      Rule rule = (Rule) target;
      elem = doc.createElement("rule");
      elem.setAttribute("class", rule.getRuleClass());
      for (Attribute attr : rule.getAttributes()) {
        AttributeValueSource attributeValueSource =
            AttributeValueSource.forRuleAndAttribute(rule, attr);
        if (attributeValueSource == AttributeValueSource.RULE
            || queryOptions.xmlShowDefaultValues) {
          // TODO(b/162524370): mayTreatMultipleAsNone should be true for types that drop multiple
          //  values.
          Iterable<Object> values =
              PossibleAttributeValues.forRuleAndAttribute(
                  rule, attr, /* mayTreatMultipleAsNone= */ false);
          Element attrElem = createValueElement(doc, attr.getType(), values, labelPrinter);
          attrElem.setAttribute("name", attr.getName());
          elem.appendChild(attrElem);
        }
      }

      // Include explicit elements for all direct inputs and outputs of a rule;
      // this goes beyond what is available from the attributes above, since it
      // may also (depending on options) include implicit outputs,
      // host-configuration outputs, and default values.
      for (Label label : rule.getSortedLabels(dependencyFilter)) {
        Element inputElem = doc.createElement("rule-input");
        inputElem.setAttribute("name", labelPrinter.toString(label));
        elem.appendChild(inputElem);
      }
      for (Label label :
          aspectResolver.computeAspectDependencies(target, dependencyFilter).values()) {
        Element inputElem = doc.createElement("rule-input");
        inputElem.setAttribute("name", labelPrinter.toString(label));
        elem.appendChild(inputElem);
      }
      for (OutputFile outputFile : rule.getOutputFiles()) {
        Element outputElem = doc.createElement("rule-output");
        outputElem.setAttribute("name", labelPrinter.toString(outputFile.getLabel()));
        elem.appendChild(outputElem);
      }
      for (String feature : rule.getPackage().getFeatures()) {
        Element outputElem = doc.createElement("rule-default-setting");
        outputElem.setAttribute("name", feature);
        elem.appendChild(outputElem);
      }
    } else if (target instanceof PackageGroup) {
      PackageGroup packageGroup = (PackageGroup) target;
      elem = doc.createElement("package-group");
      elem.setAttribute("name", packageGroup.getName());
      Element includes =
          createValueElement(doc, BuildType.LABEL_LIST, packageGroup.getIncludes(), labelPrinter);
      includes.setAttribute("name", "includes");
      elem.appendChild(includes);
      Element packages =
          createValueElement(
              doc,
              Type.STRING_LIST,
              packageGroup.getContainedPackages(packageGroupIncludesDoubleSlash),
              labelPrinter);
      packages.setAttribute("name", "packages");
      elem.appendChild(packages);
    } else if (target instanceof OutputFile) {
      OutputFile outputFile = (OutputFile) target;
      elem = doc.createElement("generated-file");
      elem.setAttribute(
          "generating-rule", labelPrinter.toString(outputFile.getGeneratingRule().getLabel()));
    } else if (target instanceof InputFile) {
      elem = doc.createElement("source-file");
      InputFile inputFile = (InputFile) target;
      if (inputFile.getName().equals("BUILD")) {
        addStarlarkFilesToElement(doc, elem, inputFile, labelPrinter);
        addFeaturesToElement(doc, elem, inputFile);
        elem.setAttribute("package_contains_errors",
            String.valueOf(inputFile.getPackage().containsErrors()));
      }

      addPackageGroupsToElement(doc, elem, inputFile, labelPrinter);
    } else if (target instanceof EnvironmentGroup) {
      EnvironmentGroup envGroup = (EnvironmentGroup) target;
      elem = doc.createElement("environment-group");
      elem.setAttribute("name", envGroup.getName());
      Element environments =
          createValueElement(doc, BuildType.LABEL_LIST, envGroup.getEnvironments(), labelPrinter);
      environments.setAttribute("name", "environments");
      elem.appendChild(environments);
      Element defaults =
          createValueElement(doc, BuildType.LABEL_LIST, envGroup.getDefaults(), labelPrinter);
      defaults.setAttribute("name", "defaults");
      elem.appendChild(defaults);
    } else if (target instanceof FakeLoadTarget) {
      elem = doc.createElement("source-file");
    } else {
      throw new IllegalArgumentException(target.toString());
    }

    elem.setAttribute("name", labelPrinter.toString(target.getLabel()));
    String location = FormatUtils.getLocation(target, relativeLocations, displaySourceFileLocation);
    if (!queryOptions.xmlLineNumbers) {
      int firstColon = location.indexOf(':');
      if (firstColon != -1) {
        location = location.substring(0, firstColon);
      }
    }

    elem.setAttribute("location", location);
    return elem;
  }

  private static void addPackageGroupsToElement(
      Document doc, Element parent, Target target, LabelPrinter labelPrinter) {
    for (Label visibilityDependency : target.getVisibility().getDependencyLabels()) {
      Element elem = doc.createElement("package-group");
      elem.setAttribute("name", labelPrinter.toString(visibilityDependency));
      parent.appendChild(elem);
    }

    for (Label visibilityDeclaration : target.getVisibility().getDeclaredLabels()) {
      Element elem = doc.createElement("visibility-label");
      elem.setAttribute("name", labelPrinter.toString(visibilityDeclaration));
      parent.appendChild(elem);
    }
  }

  private static void addFeaturesToElement(Document doc, Element parent, InputFile inputFile) {
    for (String feature : inputFile.getPackage().getFeatures()) {
      Element elem = doc.createElement("feature");
      elem.setAttribute("name", feature);
      parent.appendChild(elem);
    }
  }

  private void addStarlarkFilesToElement(
      Document doc, Element parent, InputFile inputFile, LabelPrinter labelPrinter)
      throws InterruptedException {
    Iterable<Label> dependencies =
        aspectResolver.computeBuildFileDependencies(inputFile.getPackage());

    for (Label starlarkFileDep : dependencies) {
      Element elem = doc.createElement("load");
      elem.setAttribute("name", labelPrinter.toString(starlarkFileDep));
      parent.appendChild(elem);
    }
  }

  /**
   * Creates and returns a new DOM tree for the specified attribute values. For non-configurable
   * attributes, this is a single value. For configurable attributes, this contains one value for
   * each configuration. (Only toplevel values are named attributes; list elements are unnamed.)
   *
   * <p>In the case of configurable attributes, multi-value attributes (e.g. lists) merge all
   * configured lists into an aggregate flattened list. Single-value attributes simply refrain to
   * set a value and annotate the DOM element as configurable.
   *
   * <p>(The ungainly qualified class name is required to avoid ambiguity with
   * OutputFormatter.OutputType.)
   */
  private static Element createValueElement(
      Document doc, Type<?> type, Iterable<Object> values, LabelPrinter labelPrinter) {
    // "Import static" with method scope:
    Type<?> LABEL_LIST = BuildType.LABEL_LIST;
    Type<?> LICENSE = BuildType.LICENSE;
    Type<?> STRING_LIST = Type.STRING_LIST;

    final Element elem;
    final boolean hasMultipleValues = Iterables.size(values) > 1;
    Type<?> elemType = type.getListElementType();
    if (elemType != null) { // it's a list (includes "distribs")
      elem = doc.createElement("list");
      for (Object value : values) {
        for (Object elemValue : (Collection<?>) value) {
          elem.appendChild(createValueElement(doc, elemType, elemValue, labelPrinter));
        }
      }
    } else if (type instanceof Type.DictType) {
      Set<Object> visitedValues = new HashSet<>();
      elem = doc.createElement("dict");
      Type.DictType<?, ?> dictType = (Type.DictType<?, ?>) type;
      for (Object value : values) {
        for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
          if (visitedValues.add(entry.getKey())) {
            Element pairElem = doc.createElement("pair");
            elem.appendChild(pairElem);
            pairElem.appendChild(
                createValueElement(doc, dictType.getKeyType(), entry.getKey(), labelPrinter));
            pairElem.appendChild(
                createValueElement(doc, dictType.getValueType(), entry.getValue(), labelPrinter));
          }
        }
      }
    } else if (type == LICENSE) {
      elem = createSingleValueElement(doc, "license", hasMultipleValues);
      if (!hasMultipleValues) {
        License license = (License) Iterables.getOnlyElement(values);

        Element exceptions =
            createValueElement(doc, LABEL_LIST, license.getExceptions(), labelPrinter);
        exceptions.setAttribute("name", "exceptions");
        elem.appendChild(exceptions);

        Element licenseTypes =
            createValueElement(doc, STRING_LIST, license.getLicenseTypes(), labelPrinter);
        licenseTypes.setAttribute("name", "license-types");
        elem.appendChild(licenseTypes);
      }
    } else { // INTEGER STRING LABEL DISTRIBUTION OUTPUT
      elem = createSingleValueElement(doc, type.toString(), hasMultipleValues);
      if (!hasMultipleValues && !Iterables.isEmpty(values)) {
        Object value = Iterables.getOnlyElement(values);
        // Values such as those of attribute "linkstamp" may be null.
        if (value != null) {
          try {
            if (value instanceof Label) {
              elem.setAttribute("value", labelPrinter.toString((Label) value));
            } else {
              elem.setAttribute("value", value.toString());
            }
          } catch (DOMException e) {
            elem.setAttribute("value", "[[[ERROR: could not be encoded as XML]]]");
          }
        }
      }
    }
    return elem;
  }

  private static Element createValueElement(
      Document doc, Type<?> type, Object value, LabelPrinter labelPrinter) {
    return createValueElement(doc, type, ImmutableList.of(value), labelPrinter);
  }

  /**
   * Creates the given DOM element, adding <code>configurable="yes"</code> if it represents a
   * configurable single-value attribute (configurable list attributes simply have their lists
   * merged into an aggregate flat list).
   */
  private static Element createSingleValueElement(Document doc, String name, boolean configurable) {
    Element elem = doc.createElement(name);
    if (configurable) {
      elem.setAttribute("configurable", "yes");
    }
    return elem;
  }
}
