// Copyright 2015 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.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/** Modifies a {@link MergedAndroidData} manifest for the specified densities. */
public class DensitySpecificManifestProcessor {

  static final ImmutableList<String> SCREEN_SIZES =
      ImmutableList.of("small", "normal", "large", "xlarge");
  static final ImmutableBiMap<String, String> PLAY_STORE_SUPPORTED_DENSITIES =
      ImmutableBiMap.<String, String>builder()
          .put("ldpi", "ldpi")
          .put("mdpi", "mdpi")
          .put("tvdpi", "213")
          .put("hdpi", "hdpi")
          .put("280dpi", "280")
          .put("xhdpi", "xhdpi")
          .put("400dpi", "400")
          .put("420dpi", "420")
          .put("xxhdpi", "480")
          .put("560dpi", "560")
          .put("xxxhdpi", "640")
          .build();

  private static final ImmutableMap<String, Boolean> SECURE_XML_FEATURES =
      ImmutableMap.of(
          XMLConstants.FEATURE_SECURE_PROCESSING,
          true,
          "http://xml.org/sax/features/external-general-entities",
          false,
          "http://xml.org/sax/features/external-parameter-entities",
          false,
          "http://apache.org/xml/features/nonvalidating/load-external-dtd",
          false);

  private static DocumentBuilder getSecureDocumentBuilder() throws ParserConfigurationException {
    DocumentBuilderFactory factory =
        DocumentBuilderFactory.newInstance(
            "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", null);
    factory.setValidating(false);
    factory.setXIncludeAware(false);
    for (Map.Entry<String, Boolean> featureAndValue : SECURE_XML_FEATURES.entrySet()) {
      try {
        factory.setFeature(featureAndValue.getKey(), featureAndValue.getValue());
      } catch (ParserConfigurationException e) {
        throw new FactoryConfigurationError(
            e,
            "Xerces DocumentBuilderFactory doesn't support the required security features: "
                + e.getMessage());
      }
    }
    return factory.newDocumentBuilder();
  }

  private final List<String> densities;
  private final Path out;

  /**
   * @param densities An array of string densities to use for filtering resources.
   * @param out The path to use for the generated manifest.
   */
  public DensitySpecificManifestProcessor(List<String> densities, Path out) {
    this.densities = densities;
    this.out = out;
  }

  /**
   * Modifies the manifest to contain a &lt;compatible-screens&gt; section corresponding to the
   * specified densities. If the manifest already contains a superset of the
   * &lt;compatible-screens&gt; section to be created, it is left unchanged.
   *
   * @throws ManifestProcessingException when the manifest cannot be properly modified.
   */
  public Path process(Path manifest) {
    if (densities.isEmpty()) {
      return manifest;
    }
    try {
      DocumentBuilder db = getSecureDocumentBuilder();
      Document doc = db.parse(Files.newInputStream(manifest));

      NodeList manifestElements = doc.getElementsByTagName("manifest");
      if (manifestElements.getLength() != 1) {
        throw new AndroidManifestProcessor.ManifestProcessingException(
            String.format(
                "Manifest %s does not contain exactly one <manifest> tag. " + "It contains %d.",
                manifest, manifestElements.getLength()));
      }
      Node manifestElement = manifestElements.item(0);

      Set<String> existingDensities = new LinkedHashSet<>();
      NodeList screenElements = doc.getElementsByTagName("screen");
      for (int i = 0; i < screenElements.getLength(); i++) {
        Node screen = screenElements.item(i);
        existingDensities.add(
            PLAY_STORE_SUPPORTED_DENSITIES
                .inverse()
                .get(screen.getAttributes().getNamedItem("android:screenDensity").getNodeValue()));
      }
      if (existingDensities.containsAll(densities)) {
        return manifest;
      }

      NodeList compatibleScreensElements = doc.getElementsByTagName("compatible-screens");
      for (int i = 0; i < compatibleScreensElements.getLength(); i++) {
        Node compatibleScreensElement = compatibleScreensElements.item(i);
        compatibleScreensElement.getParentNode().removeChild(compatibleScreensElement);
      }

      // If the list of densities provided in the android_binary build rule contains a density not
      // supported by the Play Store, omit the <compatible-screens> declaration from the manifest to
      // indicate that this APK supports all densities. This is a temporary fix to support new
      // density buckets until the Play Store introduces a new density targeting mechanism.
      boolean omitCompatibleScreens = false;
      for (String density : densities) {
        if (!PLAY_STORE_SUPPORTED_DENSITIES.containsKey(density)) {
          omitCompatibleScreens = true;
          System.out.println(density + " is not an accepted Play Store density.");
          System.out.println("Omitting <compatible-screens> declaration from output manifest.");
          break;
        }
      }

      if (!omitCompatibleScreens) {
        Node compatibleScreens = doc.createElement("compatible-screens");
        manifestElement.appendChild(compatibleScreens);

        for (String density : densities) {
          for (String screenSize : SCREEN_SIZES) {
            Element screen = doc.createElement("screen");
            screen.setAttribute("android:screenSize", screenSize);
            screen.setAttribute(
                "android:screenDensity", PLAY_STORE_SUPPORTED_DENSITIES.get(density));
            compatibleScreens.appendChild(screen);
          }
        }
      }

      Files.createDirectories(out.getParent());
      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      transformerFactory
          .newTransformer()
          .transform(new DOMSource(doc), new StreamResult(Files.newOutputStream(out)));
      return out;

    } catch (ParserConfigurationException | SAXException | IOException | TransformerException e) {
      throw new AndroidManifestProcessor.ManifestProcessingException(e.getMessage());
    }
  }
}
