// 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.lib.bazel.rules.android;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Ordering;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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;

/**
 * A collection of .pom contents that reference versioned archive files with dependencies.
 */
final class SdkMavenRepository {
  private enum PackagingType {
    AAR {
      @Override
      ImmutableList<String> createRule(
          String name, String archiveLabel, ImmutableList<String> dependencyLabels) {
        ImmutableList.Builder<String> ruleLines = new ImmutableList.Builder<>();
        ruleLines.add("aar_import(");
        ruleLines.add("    name = '" + name + "',");
        ruleLines.add("    aar = '" + archiveLabel + "',");
        ruleLines.add("    exports = [");
        for (String dependencyLabel : dependencyLabels) {
          ruleLines.add("        '" + dependencyLabel + "',");
        }
        ruleLines.add("    ],");
        ruleLines.add(")");
        ruleLines.add("");
        return ruleLines.build();
      }
    },
    JAR {
      @Override
      ImmutableList<String> createRule(
          String name, String archiveLabel, ImmutableList<String> dependencyLabels) {
        ImmutableList.Builder<String> ruleLines = new ImmutableList.Builder<>();
        ruleLines.add("java_import(");
        ruleLines.add("    name = '" + name + "',");
        ruleLines.add("    jars = ['" + archiveLabel + "'],");
        ruleLines.add("    exports = [");
        for (String dependencyLabel : dependencyLabels) {
          ruleLines.add("        '" + dependencyLabel + "',");
        }
        ruleLines.add("    ],");
        ruleLines.add(")");
        ruleLines.add("");
        return ruleLines.build();
      }
    },
    UNKNOWN {
      @Override
      ImmutableList<String> createRule(String name, String archiveLabel,
          ImmutableList<String> dependencyLabels) {
        ImmutableList.Builder<String> ruleLines = new ImmutableList.Builder<>();
        ruleLines.add("genrule(");
        ruleLines.add("    name = '" + name + "',");
        ruleLines.add("    outs = ['ignored_" + name + "'],");
        ruleLines.add("    cmd = 'echo Bazel does not recognize the Maven packaging type for: \""
            + archiveLabel + "\"; exit 1',");
        ruleLines.add(")");
        ruleLines.add("");
        return ruleLines.build();
      }
    };

    static PackagingType getPackagingType(String name) {
      for (PackagingType packagingType : PackagingType.values()) {
        if (packagingType.name().equalsIgnoreCase(name)) {
          return packagingType;
        }
      }
      return UNKNOWN;
    }

    abstract ImmutableList<String> createRule(
        String name, String archiveLabel, ImmutableList<String> dependencyLabels);
  }

  private final ImmutableSortedSet<Pom> poms;
  private final ImmutableSet<MavenCoordinate> allKnownCoordinates;

  private SdkMavenRepository(ImmutableSortedSet<Pom> poms) {
    this.poms = poms;
    ImmutableSet.Builder<MavenCoordinate> coordinates = new ImmutableSet.Builder<>();
    for (Pom pom : poms) {
      if (!PackagingType.getPackagingType(pom.packaging()).equals(PackagingType.UNKNOWN)) {
        coordinates.add(pom.mavenCoordinate());
      }
    }
    allKnownCoordinates = coordinates.build();
  }

  /**
   * Parses a set of maven repository directory trees looking for and parsing .pom files.
   */
  static SdkMavenRepository create(Iterable<Path> mavenRepositories) throws IOException {
    Collection<Path> pomPaths = new ArrayList<>();
    for (Path mavenRepository : mavenRepositories) {
      pomPaths.addAll(
          FileSystemUtils.traverseTree(mavenRepository, path -> path.toString().endsWith(".pom")));
    }

    ImmutableSortedSet.Builder<Pom> poms =
        new ImmutableSortedSet.Builder<>(Ordering.usingToString());
    for (Path pomPath : pomPaths) {
      try {
        Pom pom = Pom.parse(pomPath);
        if (pom != null) {
          poms.add(pom);
        }
      } catch (ParserConfigurationException | SAXException e) {
        throw new IOException(e);
      }
    }
    return new SdkMavenRepository(poms.build());
  }

  /**
   * Creates BUILD files at {@code @<android sdk>/<group id>/BUILD} containing aar_import and
   * java_import rules with dependencies as {@code exports}. The targets are named
   * {@code @<android sdk>//<group id>:<artifact id>-<version id>}.
   */
  void writeBuildFiles(Path outputDirectory) throws IOException {
    for (Pom pom : poms) {
      Path buildFilePath = outputDirectory.getRelative(pom.mavenCoordinate().groupId() + "/BUILD");

      if (!buildFilePath.getParentDirectory().exists()) {
        buildFilePath.getParentDirectory().createDirectory();
      }

      if (!buildFilePath.exists()) {
        FileSystemUtils.writeContentAsLatin1(
            buildFilePath, "package(default_visibility = [\"//visibility:public\"])\n\n");
      }

      ImmutableList.Builder<String> dependencyLabels = new ImmutableList.Builder<>();
      for (MavenCoordinate dependencyCoordinate : pom.dependencyCoordinates()) {
        // Filter out dependencies that are not present in the Maven repository or have unknown
        // packaging types.
        if (allKnownCoordinates.contains(dependencyCoordinate)) {
          dependencyLabels.add(dependencyCoordinate.targetLabel());
        }
      }

      ImmutableList<String> ruleLines = PackagingType.getPackagingType(pom.packaging())
          .createRule(
              pom.mavenCoordinate().targetName(),
              pom.archiveLabel(outputDirectory),
              dependencyLabels.build());
      FileSystemUtils.appendLinesAs(buildFilePath, StandardCharsets.ISO_8859_1, ruleLines);
    }
  }

  /**
   * Creates the contents of the exports_files rule list containing all of the archives specified by
   * the pom files in the Maven repositories.
   */
  String getExportsFiles(Path outputDirectory) {
    StringBuilder exportedFiles = new StringBuilder();
    for (Pom pom : poms) {
      exportedFiles.append(String.format(
          "    '%s',\n", pom.archivePath().relativeTo(outputDirectory).getPathString()));
    }
    return exportedFiles.toString();
  }

  /**
   * The relevant contents of a .pom file needed to populate BUILD files for aars and jars in the
   * Android SDK extras maven repositories.
   */
  @AutoValue
  abstract static class Pom {
    private static final String DEFAULT_PACKAGING = "jar";

    static Pom parse(Path path) throws IOException, ParserConfigurationException, SAXException {
      Document pomDocument = null;
      try (InputStream in = path.getInputStream()) {
        pomDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in);
      }
      Node packagingNode = pomDocument.getElementsByTagName("packaging").item(0);
      String packaging = packagingNode == null ? DEFAULT_PACKAGING : packagingNode.getTextContent();
      MavenCoordinate coordinate = MavenCoordinate.create(
          pomDocument.getElementsByTagName("groupId").item(0).getTextContent(),
          pomDocument.getElementsByTagName("artifactId").item(0).getTextContent(),
          pomDocument.getElementsByTagName("version").item(0).getTextContent());

      ImmutableSortedSet.Builder<MavenCoordinate> dependencyCoordinates =
          new ImmutableSortedSet.Builder<>(Ordering.usingToString());
      NodeList dependencies = pomDocument.getElementsByTagName("dependency");
      for (int i = 0; i < dependencies.getLength(); i++) {
        if (dependencies.item(i) instanceof Element) {
          Element dependency = (Element) dependencies.item(i);
          dependencyCoordinates.add(MavenCoordinate.create(
              dependency.getElementsByTagName("groupId").item(0).getTextContent(),
              dependency.getElementsByTagName("artifactId").item(0).getTextContent(),
              dependency.getElementsByTagName("version").item(0).getTextContent()));
        }
      }

      return new AutoValue_SdkMavenRepository_Pom(
          path, packaging, coordinate, dependencyCoordinates.build());
    }

    abstract Path path();

    abstract String packaging();

    abstract MavenCoordinate mavenCoordinate();

    abstract ImmutableSortedSet<MavenCoordinate> dependencyCoordinates();

    String name() {
      String pomFilename = path().getBaseName();
      return pomFilename.substring(0, pomFilename.lastIndexOf(".pom"));
    }

    Path archivePath() {
      return path().getParentDirectory().getRelative(name() + "." + packaging());
    }

    /** The label for the .aar or .jar file in the repository. */
    String archiveLabel(Path outputDirectory) {
      return "//:" + archivePath().relativeTo(outputDirectory);
    }
  }

  /**
   * A 3-tuple of group id, artifact id and version used to identify Maven targets.
   */
  @AutoValue
  abstract static class MavenCoordinate {
    static MavenCoordinate create(String groupId, String artifactId, String version) {
      return new AutoValue_SdkMavenRepository_MavenCoordinate(groupId, artifactId, version);
    }

    abstract String groupId();

    abstract String artifactId();

    abstract String version();

    /** The target name for the java_import or aar_import for the Maven coordinate. */
    String targetName() {
      return artifactId() + "-" + version();
    }

    /** The target label for the java_import or aar_import for the Maven coordinate. */
    String targetLabel() {
      return "//" + groupId() + ":" + targetName();
    }
  }
}
