// Copyright 2017 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.

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;

/**
 * Output a jar file containing all classes on the JDK 8 platform classpath of the default java
 * compiler of the current JDK.
 *
 * <p>usage: DumpPlatformClassPath <target release> output.jar
 */
public class DumpPlatformClassPath {

  public static void main(String[] args) throws IOException {
    if (args.length != 2) {
      System.err.println("usage: DumpPlatformClassPath <target release> <output jar>");
      System.exit(1);
    }
    String targetRelease = args[0];
    try (OutputStream os = Files.newOutputStream(Paths.get(args[1]));
        BufferedOutputStream bos = new BufferedOutputStream(os, 65536);
        JarOutputStream jos = new JarOutputStream(bos)) {
      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
      StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, UTF_8);
      if (isJdk9OrLater()) {
        // this configures the filemanager to use a JDK 8 bootclasspath
        compiler.getTask(
            null, fileManager, null, Arrays.asList("--release", targetRelease), null, null);
        Iterable<Path> paths;
        try {
          paths =
              (Iterable<Path>)
                  StandardJavaFileManager.class
                      .getMethod("getLocationAsPaths", Location.class)
                      .invoke(fileManager, StandardLocation.PLATFORM_CLASS_PATH);
        } catch (ReflectiveOperationException e) {
          throw new LinkageError(e.getMessage(), e);
        }
        for (Path path : paths) {
          Files.walkFileTree(
              path,
              new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                    throws IOException {
                  if (file.getFileName().toString().endsWith(".sig")) {
                    String outputPath = path.relativize(file).toString();
                    outputPath =
                        outputPath.substring(0, outputPath.length() - ".sig".length()) + ".class";
                    addEntry(jos, outputPath, Files.readAllBytes(file));
                  }
                  return FileVisitResult.CONTINUE;
                }
              });
        }
      } else {
        for (JavaFileObject fileObject :
            fileManager.list(
                StandardLocation.PLATFORM_CLASS_PATH,
                "",
                EnumSet.of(Kind.CLASS),
                /* recurse= */ true)) {
          String binaryName =
              fileManager.inferBinaryName(StandardLocation.PLATFORM_CLASS_PATH, fileObject);
          addEntry(
              jos,
              binaryName.replace('.', '/') + ".class",
              toByteArray(fileObject.openInputStream()));
        }
      }
    }
  }

  // Use a fixed timestamp for deterministic jar output.
  private static final long FIXED_TIMESTAMP =
      new GregorianCalendar(2010, 0, 1, 0, 0, 0).getTimeInMillis();

  private static void addEntry(JarOutputStream jos, String name, byte[] bytes) throws IOException {
    JarEntry je = new JarEntry(name);
    je.setTime(FIXED_TIMESTAMP);
    je.setMethod(ZipEntry.STORED);
    je.setSize(bytes.length);
    CRC32 crc = new CRC32();
    crc.update(bytes);
    je.setCrc(crc.getValue());
    jos.putNextEntry(je);
    jos.write(bytes);
  }

  private static byte[] toByteArray(InputStream is) throws IOException {
    byte[] buffer = new byte[8192];
    ByteArrayOutputStream boas = new ByteArrayOutputStream();
    while (true) {
      int r = is.read(buffer);
      if (r == -1) {
        break;
      }
      boas.write(buffer, 0, r);
    }
    return boas.toByteArray();
  }

  private static boolean isJdk9OrLater() {
    return Double.parseDouble(System.getProperty("java.class.version")) >= 53.0;
  }
}
