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

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteStreams;
import org.objectweb.asm.Opcodes;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;

/** JUnit tests for ijar tool. */
@RunWith(JUnit4.class)
public class IjarTests {

  private static File getTmpDir() {
    String tmpdir = System.getenv("TEST_TMPDIR");
    if (tmpdir == null) {
      // Fall back on the system temporary directory
      tmpdir = System.getProperty("java.io.tmpdir");
    }
    if (tmpdir == null) {
      fail("TEST_TMPDIR environment variable is not set!");
    }
    return new File(tmpdir);
  }

  DiagnosticCollector<JavaFileObject> diagnostics;

  private JavaCompiler.CompilationTask makeCompilationTask(String... files) throws IOException {
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    fileManager.setLocation(
        StandardLocation.CLASS_PATH,
        Arrays.asList(new File("third_party/ijar/test/interface_ijar_testlib.jar")));
    fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(getTmpDir()));
    diagnostics = new DiagnosticCollector<JavaFileObject>();
    return compiler.getTask(
        null,
        fileManager,
        diagnostics,
        Arrays.asList("-Xlint:deprecation"), // used for deprecation tests
        null,
        fileManager.getJavaFileObjects(files));
  }

  /**
   * Test that the ijar tool preserves private nested classes as they may be exposed through public
   * API. This test relies on an interface jar provided through the build rule
   * :interface_ijar_testlib and the Java source file PrivateNestedClass.java.
   */
  @Test
  public void testPrivateNestedClass() throws IOException {
    if (!makeCompilationTask("third_party/ijar/test/PrivateNestedClass.java").call()) {
      fail(getFailedCompilationMessage());
    }
  }

  /** Test that the ijar tool preserves annotations, especially @Target meta-annotation. */
  @Test
  public void testRestrictedAnnotations() throws IOException {
    assertFalse(makeCompilationTask("third_party/ijar/test/UseRestrictedAnnotation.java").call());
  }

  /**
   * Test that the ijar tool preserves private nested classes as they may be exposed through public
   * API. This test relies on an interface jar provided through the build rule
   * :interface_ijar_testlib and the Java source file PrivateNestedClass.java.
   */
  @Test
  public void testDeprecatedParts() throws IOException {
    if (!makeCompilationTask("third_party/ijar/test/UseDeprecatedParts.java").call()) {
      fail(getFailedCompilationMessage());
    }
    int deprecatedWarningCount = 0;
    for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
      if ((diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING)
          &&
          // Java 6:
          (diagnostic.getMessage(Locale.ENGLISH).startsWith("[deprecation]")
              ||
              // Java 7:
              diagnostic.getMessage(Locale.ENGLISH).contains("has been deprecated"))) {
        deprecatedWarningCount++;
      }
    }
    assertThat(deprecatedWarningCount).isAtLeast(16);
  }

  /**
   * Test that the ijar tool preserves EnclosingMethod attributes and doesn't prevent annotation
   * processors from accessing all the elements in a package.
   */
  @Test
  public void testEnclosingMethod() throws IOException {
    JavaCompiler.CompilationTask task =
        makeCompilationTask("third_party/ijar/test/package-info.java");
    task.setProcessors(
        Arrays.asList(
            new AbstractProcessor() {

              @Override
              public SourceVersion getSupportedSourceVersion() {
                return SourceVersion.latestSupported();
              }

              @Override
              public Set<String> getSupportedAnnotationTypes() {
                return Collections.singleton("*");
              }

              @Override
              public boolean process(
                  Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
                roundEnv.getElementsAnnotatedWith(java.lang.Override.class);
                return false;
              }
            }));
    if (!task.call()) {
      fail(getFailedCompilationMessage());
    }
  }

  @Test
  public void testVerifyStripping() throws Exception {
    ZipFile zip = new ZipFile("third_party/ijar/test/interface_ijar_testlib.jar");
    Enumeration<? extends ZipEntry> entries = zip.entries();
    while (entries.hasMoreElements()) {
      ZipEntry entry = entries.nextElement();
      ClassReader reader = new ClassReader(zip.getInputStream(entry));
      StripVerifyingVisitor verifier = new StripVerifyingVisitor();

      reader.accept(verifier, 0);

      if (verifier.errors.size() > 0) {
        StringBuilder builder = new StringBuilder();
        builder.append("Verification of ");
        builder.append(entry.getName());
        builder.append(" failed: ");
        for (String msg : verifier.errors) {
          builder.append(msg);
          builder.append("\t");
        }
        fail(builder.toString());
      }
    }
  }

  private String getFailedCompilationMessage() {
    StringBuilder builder = new StringBuilder();
    builder.append("Build failed unexpectedly");
    for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
      builder.append(
          String.format(
              "\t%s line %d column %d: %s",
              diagnostic.getKind().toString(),
              diagnostic.getLineNumber(),
              diagnostic.getColumnNumber(),
              diagnostic.getMessage(Locale.ENGLISH)));
    }
    return builder.toString();
  }

  @Test
  public void localAndAnonymous() throws Exception {
    Map<String, byte[]> lib = readJar("third_party/ijar/test/liblocal_and_anonymous_lib.jar");
    Map<String, byte[]> ijar = readJar("third_party/ijar/test/local_and_anonymous-interface.jar");

    assertThat(lib.keySet())
        .containsExactly(
            "LocalAndAnonymous$1.class",
            "LocalAndAnonymous$2.class",
            "LocalAndAnonymous$1LocalClass.class",
            "LocalAndAnonymous.class",
            "LocalAndAnonymous$NestedClass.class",
            "LocalAndAnonymous$InnerClass.class",
            "LocalAndAnonymous$PrivateInnerClass.class");
    assertThat(ijar.keySet())
        .containsExactly(
            "LocalAndAnonymous.class",
            "LocalAndAnonymous$NestedClass.class",
            "LocalAndAnonymous$InnerClass.class",
            "LocalAndAnonymous$PrivateInnerClass.class");

    assertThat(innerClasses(lib.get("LocalAndAnonymous.class")))
        .isEqualTo(
            ImmutableMap.<String, String>builder()
                .put("LocalAndAnonymous$1", "null")
                .put("LocalAndAnonymous$2", "null")
                .put("LocalAndAnonymous$1LocalClass", "null")
                .put("LocalAndAnonymous$InnerClass", "LocalAndAnonymous")
                .put("LocalAndAnonymous$NestedClass", "LocalAndAnonymous")
                .put("LocalAndAnonymous$PrivateInnerClass", "LocalAndAnonymous")
                .buildOrThrow());
    assertThat(innerClasses(ijar.get("LocalAndAnonymous.class")))
        .containsExactly(
            "LocalAndAnonymous$InnerClass", "LocalAndAnonymous",
            "LocalAndAnonymous$NestedClass", "LocalAndAnonymous",
            "LocalAndAnonymous$PrivateInnerClass", "LocalAndAnonymous");
  }

  static Map<String, byte[]> readJar(String path) throws IOException {
    Map<String, byte[]> classes = new HashMap<>();
    try (JarFile jf = new JarFile(path)) {
      Enumeration<JarEntry> entries = jf.entries();
      while (entries.hasMoreElements()) {
        JarEntry je = entries.nextElement();
        if (!je.getName().endsWith(".class")
            && !je.getName().endsWith(".kotlin_builtins")
            && !je.getName().endsWith(".kotlin_module")
            && !je.getName().endsWith(".tasty")) {
          continue;
        }
        classes.put(je.getName(), ByteStreams.toByteArray(jf.getInputStream(je)));
      }
    }
    return classes;
  }

  static Map<String, String> innerClasses(byte[] bytes) {
    final Map<String, String> innerClasses = new HashMap<>();
    new ClassReader(bytes)
        .accept(
            new ClassVisitor(Opcodes.ASM9) {
              @Override
              public void visitInnerClass(
                  String name, String outerName, String innerName, int access) {
                innerClasses.put(name, String.valueOf(outerName));
              }
            },
            /* parsingOptions= */ 0);
    return innerClasses;
  }

  @Test
  public void moduleInfo() throws Exception {
    Map<String, byte[]> lib = readJar("third_party/ijar/test/module_info-interface.jar");
    assertThat(lib.keySet())
        .containsExactly("java/lang/String.class", "module-info.class", "foo/module-info.class");
    // ijar passes module-infos through unmodified, so it doesn't care that these ones are bogus
    assertThat(new String(lib.get("module-info.class"), UTF_8)).isEqualTo("hello");
    assertThat(new String(lib.get("foo/module-info.class"), UTF_8)).isEqualTo("goodbye");
  }

  @Test
  public void kotlinModule() throws Exception {
    Map<String, byte[]> lib = readJar("third_party/ijar/test/kotlin_module-interface.jar");
    assertThat(lib.keySet())
        .containsExactly(
            "java/lang/String.class",
            "kotlin/kotlin.kotlin_builtins",
            "META-INF/bar.kotlin_module");
    // ijar passes kotlin modules and builtins through unmodified
    assertThat(new String(lib.get("META-INF/bar.kotlin_module"), UTF_8)).isEqualTo("hello");
    assertThat(new String(lib.get("kotlin/kotlin.kotlin_builtins"), UTF_8)).isEqualTo("goodbye");
  }

  @Test
  public void scalaTasty() throws Exception {
    Map<String, byte[]> lib = readJar("third_party/ijar/test/scala_tasty-interface.jar");
    assertThat(lib.keySet()).containsExactly("java/lang/String.class", "Bar.tasty");
    // ijar passes scala tasty files through unmodified
    assertThat(new String(lib.get("Bar.tasty"), UTF_8)).isEqualTo("hello");
  }

  @Test
  public void testTargetLabel() throws Exception {
    try (JarFile jf =
        new JarFile("third_party/ijar/test/interface_ijar_testlib_with_target_label.jar")) {
      ImmutableList<String> entries = jf.stream().map(JarEntry::getName).collect(toImmutableList());
      assertThat(entries.get(0)).isEqualTo("META-INF/");
      assertThat(entries.get(1)).isEqualTo("META-INF/MANIFEST.MF");
      Manifest manifest = jf.getManifest();
      Attributes attributes = manifest.getMainAttributes();
      assertThat(attributes.getValue("Target-Label")).isEqualTo("//foo:foo");
      assertThat(attributes.getValue("Injecting-Rule-Kind")).isEqualTo("foo_library");
      assertThat(jf.getEntry(JarFile.MANIFEST_NAME).getLastModifiedTime().toInstant())
          .isEqualTo(
              LocalDateTime.of(2010, 1, 1, 0, 0, 0).atZone(ZoneOffset.systemDefault()).toInstant());
    }
  }

  @Test
  public void testEmptyWithTargetLabel() throws Exception {
    try (JarFile jf = new JarFile("third_party/ijar/test/empty_with_target_label.jar")) {
      Manifest manifest = jf.getManifest();
      Attributes attributes = manifest.getMainAttributes();
      assertThat(attributes.getValue("Target-Label")).isEqualTo("//empty");
      assertThat(jf.getEntry(JarFile.MANIFEST_NAME).getLastModifiedTime().toInstant())
          .isEqualTo(
              LocalDateTime.of(2010, 1, 1, 0, 0, 0).atZone(ZoneOffset.systemDefault()).toInstant());
    }
  }

  // Tests --nostrip_jar with a jar that already has a manifest, but no target label
  @Test
  public void testNoStripJarWithManifest() throws Exception {
    JarFile original = new JarFile("third_party/ijar/test/jar-with-manifest.jar");
    JarFile stripped = new JarFile("third_party/ijar/test/jar-with-manifest-nostrip.jar");
    try {
      ImmutableList<String> strippedEntries =
          stripped.stream().map(JarEntry::getName).collect(toImmutableList());
      assertThat(strippedEntries.get(0)).isEqualTo("META-INF/");
      assertThat(strippedEntries.get(1)).isEqualTo("META-INF/MANIFEST.MF");
      Manifest manifest = stripped.getManifest();
      Attributes attributes = manifest.getMainAttributes();
      assertThat(attributes.getValue("Manifest-Version")).isEqualTo("1.0");
      // Created-By was already in manifest, doesn't get overwritten
      assertThat(attributes.getValue("Created-By")).isEqualTo("test-code");
      assertThat(attributes.getValue("Target-Label")).isEqualTo("//foo:foo");
      assertNonManifestFilesBitIdentical(original, stripped);
    } finally {
      original.close();
      stripped.close();
    }
  }

  // Tests --nostrip_jar with a jar that already has a manifest with a target label
  @Test
  public void testNoStripJarWithManifestAndTargetLabel() throws Exception {
    JarFile original = new JarFile("third_party/ijar/test/jar-with-manifest-and-target-label.jar");
    JarFile stripped =
        new JarFile("third_party/ijar/test/jar-with-manifest-and-target-label-nostrip.jar");
    try {
      ImmutableList<String> strippedEntries =
          stripped.stream().map(JarEntry::getName).collect(toImmutableList());
      assertThat(strippedEntries.get(0)).isEqualTo("META-INF/");
      assertThat(strippedEntries.get(1)).isEqualTo("META-INF/MANIFEST.MF");
      Manifest manifest = stripped.getManifest();
      Attributes attributes = manifest.getMainAttributes();
      assertThat(attributes.getValue("Manifest-Version")).isEqualTo("1.0");
      // Created-By was already in manifest, doesn't get overwritten
      assertThat(attributes.getValue("Created-By")).isEqualTo("test-code");
      assertThat(attributes.getValue("Target-Label")).isEqualTo("//foo:foo");
      assertNonManifestFilesBitIdentical(original, stripped);
    } finally {
      original.close();
      stripped.close();
    }
  }

  // Tests --nostrip_jar with a jar that didn't already have a manifest
  @Test
  public void testNoStripJarWithoutManifest() throws Exception {
    JarFile original = new JarFile("third_party/ijar/test/jar-without-manifest.jar");
    JarFile stripped = new JarFile("third_party/ijar/test/jar-without-manifest-nostrip.jar");
    try {
      ImmutableList<String> strippedEntries =
          stripped.stream().map(JarEntry::getName).collect(toImmutableList());
      assertThat(strippedEntries.get(0)).isEqualTo("META-INF/");
      assertThat(strippedEntries.get(1)).isEqualTo("META-INF/MANIFEST.MF");
      Manifest manifest = stripped.getManifest();
      Attributes attributes = manifest.getMainAttributes();
      assertThat(attributes.getValue("Manifest-Version")).isEqualTo("1.0");
      assertThat(attributes.getValue("Created-By")).isEqualTo("bazel");
      assertThat(attributes.getValue("Target-Label")).isEqualTo("//foo:foo");
      assertNonManifestFilesBitIdentical(original, stripped);
    } finally {
      original.close();
      stripped.close();
    }
  }

  @Test
  public void testPreserveManifestSections() throws Exception {
    try (JarFile original =
            new JarFile(
                "third_party/ijar/test/jar-with-target-label-and-manifest-sections-nostrip.jar");
        JarFile stripped =
            new JarFile("third_party/ijar/test/jar-with-manifest-sections-nostrip.jar")) {
      ImmutableList<String> strippedEntries =
          stripped.stream().map(JarEntry::getName).collect(toImmutableList());

      assertThat(strippedEntries.get(0)).isEqualTo("META-INF/");
      assertThat(strippedEntries.get(1)).isEqualTo("META-INF/MANIFEST.MF");
      Manifest manifest = stripped.getManifest();
      Attributes attributes = manifest.getMainAttributes();
      assertThat(attributes.getValue("Target-Label")).isEqualTo("//foo:foo");
      assertNonManifestFilesBitIdentical(original, stripped);

      Attributes sectionAttributes1 = manifest.getAttributes("foo");
      assertThat(sectionAttributes1.getValue("Foo")).isEqualTo("bar");

      Attributes sectionAttributes2 = manifest.getAttributes("baz");
      assertThat(sectionAttributes2.getValue("Another")).isEqualTo("bar");
    }
  }

  @Test
  public void testPreserveManifestSectionsAndUpdateExistingTargetLabel() throws Exception {
    try (JarFile original =
            new JarFile(
                "third_party/ijar/test/jar-with-target-label-and-manifest-sections-nostrip.jar");
        JarFile stripped =
            new JarFile(
                "third_party/ijar/test/jar-with-target-label-and-manifest-sections-nostrip.jar")) {
      ImmutableList<String> strippedEntries =
          stripped.stream().map(JarEntry::getName).collect(toImmutableList());

      assertThat(strippedEntries.get(0)).isEqualTo("META-INF/");
      assertThat(strippedEntries.get(1)).isEqualTo("META-INF/MANIFEST.MF");
      Manifest manifest = stripped.getManifest();
      Attributes attributes = manifest.getMainAttributes();
      assertThat(attributes.getValue("Target-Label")).isEqualTo("//foo:foo");
      assertNonManifestFilesBitIdentical(original, stripped);

      Attributes sectionAttributes1 = manifest.getAttributes("foo");
      assertThat(sectionAttributes1.getValue("Foo")).isEqualTo("bar");

      Attributes sectionAttributes2 = manifest.getAttributes("baz");
      assertThat(sectionAttributes2.getValue("Another")).isEqualTo("bar");
    }
  }

  // Tests idempotence of --nostrip
  @Test
  public void testNoStripIdempotence() throws Exception {
    byte[] original =
        Files.readAllBytes(Paths.get("third_party/ijar/test/jar-without-manifest-nostrip.jar"));
    byte[] stripped =
        Files.readAllBytes(
            Paths.get("third_party/ijar/test/jar-without-manifest-nostrip-idempotence.jar"));
    assertThat(original).isEqualTo(stripped);
  }

  @Test
  public void metaInfTtransitive() throws Exception {
    Map<String, byte[]> lib = readJar("third_party/ijar/test/meta_inf_transitive-interface.jar");
    assertThat(lib.keySet()).containsExactly("java/lang/String.class");
  }

  private static void assertNonManifestFilesBitIdentical(JarFile original, JarFile stripped)
      throws IOException {
    // Make sure that all other files came across bitwise equal
    for (String classEntry :
        original.stream()
            .map(JarEntry::getName)
            .filter(name -> !name.equals("META-INF/MANIFEST.MF"))
            .collect(toImmutableList())) {
      ZipEntry originalEntry = original.getEntry(classEntry);
      ZipEntry strippedEntry = stripped.getEntry(classEntry);
      InputStream originalStream = original.getInputStream(originalEntry);
      InputStream strippedStream = stripped.getInputStream(strippedEntry);
      assertThat(ByteStreams.toByteArray(strippedStream))
          .isEqualTo(ByteStreams.toByteArray(originalStream));
    }
  }
}
