// 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.buildjar.genclass;

import static com.google.common.collect.ImmutableSet.toImmutableSet;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.buildjar.jarhelper.JarCreator;
import com.google.devtools.build.buildjar.proto.JavaCompilation.CompilationUnit;
import com.google.devtools.build.buildjar.proto.JavaCompilation.Manifest;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.function.Predicate;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Stream;

/**
 * GenClass post-processes the output of a Java compilation, and produces a jar containing only the
 * class files for sources that were generated by annotation processors.
 */
public class GenClass {

  /** Recursively delete a directory. */
  private static void deleteTree(Path directory) throws IOException {
    if (directory.toFile().exists()) {
      Files.walkFileTree(
          directory,
          new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException {
              Files.delete(file);
              return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc)
                throws IOException {
              Files.delete(dir);
              return FileVisitResult.CONTINUE;
            }
          });
    }
  }

  public static void main(String[] args) throws IOException {
    GenClassOptions options = GenClassOptionsParser.parse(Arrays.asList(args));
    Manifest manifest = readManifest(options.manifest());

    if (!options.getGeneratedSourceJars().isEmpty()) {
      Manifest generatedJarsManifest = readGeneratedSourceJars(options.getGeneratedSourceJars());
      manifest = Manifest.newBuilder(manifest).mergeFrom(generatedJarsManifest).build();
    }

    deleteTree(options.tempDir());
    Files.createDirectories(options.tempDir());
    extractGeneratedClasses(options.classJar(), manifest, options.tempDir());
    writeOutputJar(options);
  }

  /** Reads the compilation manifest. */
  private static Manifest readManifest(Path path) throws IOException {
    Manifest manifest;
    try (InputStream inputStream = Files.newInputStream(path)) {
      manifest = Manifest.parseFrom(inputStream);
    }
    return manifest;
  }

  /** Reads the list of source jars and generates a Manifest based on the jars' entries. */
  @VisibleForTesting
  static Manifest readGeneratedSourceJars(List<Path> generatedSourceJarPaths) throws IOException {

    Manifest.Builder manifestBuilder = Manifest.newBuilder();
    for (Path generatedSourceJarPath : generatedSourceJarPaths) {

      try (JarFile jar = new JarFile(generatedSourceJarPath.toFile())) {

        Enumeration<JarEntry> entries = jar.entries();
        while (entries.hasMoreElements()) {

          JarEntry entry = entries.nextElement();
          String path = entry.getName();
          if (!path.endsWith(".java")) {
            continue;
          }

          // This assumes that there is only 1 compilation unit in the Java file, and that the Java
          // file's package matches its path in the jar.

          int lastSlash = path.lastIndexOf("/");
          String className = path.substring(lastSlash + 1, path.length() - ".java".length());
          String pkg;
          if (lastSlash == -1) {
            pkg = "";
          } else {
            pkg = path.substring(0, lastSlash).replace('/', '.');
          }
          manifestBuilder.addCompilationUnit(
              CompilationUnit.newBuilder()
                  .setPath(path)
                  .setPkg(pkg)
                  .setGeneratedByAnnotationProcessor(true)
                  .addTopLevel(className)
                  .build());
        }
      }
    }

    return manifestBuilder.build();
  }

  /**
   * For each top-level class in the compilation matching the given predicate, determine the path
   * prefix of classes corresponding to that compilation unit.
   */
  @VisibleForTesting
  static ImmutableSet<String> getPrefixes(Manifest manifest, Predicate<CompilationUnit> p) {
    return manifest
        .getCompilationUnitList()
        .stream()
        .filter(p)
        .flatMap(unit -> getUnitPrefixes(unit))
        .collect(toImmutableSet());
  }

  /**
   * Prefixes are used to correctly handle inner classes, e.g. the top-level class "c.g.Foo" may
   * correspond to "c/g/Foo.class" and also "c/g/Foo$Inner.class" or "c/g/Foo$0.class".
   */
  private static Stream<String> getUnitPrefixes(CompilationUnit unit) {
    String pkg;
    if (unit.hasPkg()) {
      pkg = unit.getPkg().replace('.', '/') + "/";
    } else {
      pkg = "";
    }
    return unit.getTopLevelList().stream().map(toplevel -> pkg + toplevel);
  }

  /**
   * Unzip all the class files that correspond to annotation processor- generated sources into the
   * temporary directory.
   */
  private static void extractGeneratedClasses(Path classJar, Manifest manifest, Path tempDir)
      throws IOException {
    ImmutableSet<String> generatedFilePrefixes =
        getPrefixes(manifest, unit -> unit.getGeneratedByAnnotationProcessor());
    ImmutableSet<String> userWrittenFilePrefixes =
        getPrefixes(manifest, unit -> !unit.getGeneratedByAnnotationProcessor());
    try (JarFile jar = new JarFile(classJar.toFile())) {
      Enumeration<JarEntry> entries = jar.entries();
      while (entries.hasMoreElements()) {
        JarEntry entry = entries.nextElement();
        String name = entry.getName();
        if (!name.endsWith(".class")) {
          continue;
        }
        String className = name.substring(0, name.length() - ".class".length());
        if (prefixesContains(generatedFilePrefixes, className)
            // Assume that prefixes that don't correspond to a known hand-written source are
            // generated.
            || !prefixesContains(userWrittenFilePrefixes, className)) {
          Files.createDirectories(tempDir.resolve(name).getParent());
          // InputStream closing: JarFile extends ZipFile, and ZipFile.close() will close all of the
          // input streams previously returned by invocations of the getInputStream method.
          // See https://docs.oracle.com/javase/8/docs/api/java/util/zip/ZipFile.html#close--
          Files.copy(jar.getInputStream(entry), tempDir.resolve(name));
        }
      }
    }
  }

  /**
   * We want to include inner classes for generated source files, but a class whose name contains
   * '$' isn't necessarily an inner class. Check whether any prefix of the class name that ends with
   * '$' matches one of the top-level class names.
   */
  private static boolean prefixesContains(ImmutableSet<String> prefixes, String className) {
    if (prefixes.contains(className)) {
      return true;
    }
    for (int i = className.indexOf('$'); i != -1; i = className.indexOf('$', i + 1)) {
      if (prefixes.contains(className.substring(0, i))) {
        return true;
      }
    }
    return false;
  }

  /** Writes the generated class files to the output jar. */
  private static void writeOutputJar(GenClassOptions options) throws IOException {
    JarCreator output = new JarCreator(options.outputJar().toString());
    output.setCompression(true);
    output.setNormalize(true);
    output.addDirectory(options.tempDir().toString());
    output.execute();
  }
}
