// Copyright 2020 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.r8.desugar;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.android.r8.R8Utils.INTERFACE_COMPANION_SUFFIX;
import static org.objectweb.asm.Opcodes.V1_7;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.android.desugar.proto.DesugarDeps;
import com.google.devtools.build.android.desugar.proto.DesugarDeps.Dependency;
import com.google.devtools.build.android.desugar.proto.DesugarDeps.DesugarDepsInfo;
import com.google.devtools.build.android.desugar.proto.DesugarDeps.InterfaceDetails;
import com.google.devtools.build.android.desugar.proto.DesugarDeps.InterfaceWithCompanion;
import com.google.devtools.build.android.r8.DescriptorUtils;
import com.google.devtools.build.android.r8.Desugar;
import com.google.devtools.build.android.r8.FileUtils;
import com.google.devtools.build.android.r8.desugar.basic.A;
import com.google.devtools.build.android.r8.desugar.basic.B;
import com.google.devtools.build.android.r8.desugar.basic.C;
import com.google.devtools.build.android.r8.desugar.basic.I;
import com.google.devtools.build.android.r8.desugar.basic.J;
import com.google.devtools.build.android.r8.desugar.basic.K;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.function.Consumer;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;

/** Basic test of D8 desugar */
@RunWith(JUnit4.class)
public class DesugarBasicTest {
  private Path basic;
  private Path desugared;
  private Path desugaredClasspath;
  private Path desugaredWithDependencyMetadata;
  private Path doubleDesugaredWithDependencyMetadata;
  private Path desugaredClasspathWithDependencyMetadata;
  private Path desugaredWithDependencyMetadataMissingInterface;

  @Before
  public void setup() {
    // Jar file with the compiled Java code in the sub-package basic before desugaring.
    basic = Paths.get(System.getProperty("DesugarBasicTest.testdata_basic"));
    // Jar file with the compiled Java code in the sub-package basic after desugaring.
    desugared = Paths.get(System.getProperty("DesugarBasicTest.testdata_basic_desugared"));
    // Jar file with the compiled Java code in the sub-package basic after desugaring with all
    // interfaces on classpath.
    desugaredClasspath =
        Paths.get(System.getProperty("DesugarBasicTest.testdata_basic_desugared_classpath"));
    // Jar file with the compiled Java code in the sub-package basic after desugaring with
    // collected dependency metadata included.
    desugaredWithDependencyMetadata =
        Paths.get(
            System.getProperty(
                "DesugarBasicTest.testdata_basic_desugared_with_dependency_metadata"));
    // Same as testdata_basic_desugared_with_dependency_metadata, but where the input is instead the
    // already desugared code (i.e., testdata_basic_desugared)
    doubleDesugaredWithDependencyMetadata =
        Paths.get(
            System.getProperty(
                "DesugarBasicTest.testdata_basic_double_desugared_with_dependency_metadata"));
    // Jar file with the compiled Java code in the sub-package basic after desugaring with all
    // interfaces on classpath with collected dependency metadata included.
    desugaredClasspathWithDependencyMetadata =
        Paths.get(
            System.getProperty(
                "DesugarBasicTest.testdata_basic_desugared_classpath_with_dependency_metadata"));
    // Jar file with the compiled Java code in the sub-package basic after desugaring with missing
    // interface.
    desugaredWithDependencyMetadataMissingInterface =
        Paths.get(
            System.getProperty(
                "DesugarBasicTest.testdata_basic_desugared_with_dependency_metadata_missing_interface"));
  }

  @Test
  public void checkBeforeDesugar() throws Exception {
    DesugarInfoCollector desugarInfoCollector = new DesugarInfoCollector();
    forAllClasses(basic, desugarInfoCollector);
    assertThat(desugarInfoCollector.getLargestMajorClassFileVersion()).isGreaterThan(V1_7);
    assertThat(desugarInfoCollector.getNumberOfInvokeDynamic()).isGreaterThan(0);
    assertThat(desugarInfoCollector.getNumberOfDefaultMethods()).isGreaterThan(0);
    assertThat(desugarInfoCollector.getNumberOfDesugaredLambdas()).isEqualTo(0);
    assertThat(desugarInfoCollector.getNumberOfCompanionClasses()).isEqualTo(0);
  }

  @Test
  public void checkAfterDesugar() throws Exception {
    for (Path jar : ImmutableList.of(desugared, desugaredWithDependencyMetadata)) {
      DesugarInfoCollector desugarInfoCollector = new DesugarInfoCollector();
      forAllClasses(jar, desugarInfoCollector);
      // TODO(b/153971249): The class file version of desugared class files should be Java 7.
      // assertThat(lambdaUse.getMajorCfVersion()).isEqualTo(V1_7);
      assertThat(desugarInfoCollector.getNumberOfInvokeDynamic()).isEqualTo(0);
      assertThat(desugarInfoCollector.getNumberOfDefaultMethods()).isEqualTo(0);
      assertThat(desugarInfoCollector.getNumberOfDesugaredLambdas()).isEqualTo(1);
      assertThat(desugarInfoCollector.getNumberOfCompanionClasses()).isEqualTo(3);
    }
  }

  @Test
  public void checkAfterDesugarClasspath() throws Exception {
    DesugarInfoCollector desugarInfoCollector = new DesugarInfoCollector();
    forAllClasses(desugaredClasspath, desugarInfoCollector);
    // TODO(b/153971249): The class file version of desugared class files should be Java 7.
    // assertThat(lambdaUse.getMajorCfVersion()).isEqualTo(V1_7);
    assertThat(desugarInfoCollector.getNumberOfInvokeDynamic()).isEqualTo(0);
    assertThat(desugarInfoCollector.getNumberOfDefaultMethods()).isEqualTo(0);
    assertThat(desugarInfoCollector.getNumberOfDesugaredLambdas()).isEqualTo(1);
    assertThat(desugarInfoCollector.getNumberOfCompanionClasses()).isEqualTo(0);
  }

  @Test
  public void checkMetaDataAfterDoubleDesugaring() throws Exception {
    DesugarDepsInfo info = extractDesugarDeps(doubleDesugaredWithDependencyMetadata);
    assertThat(info.getInterfaceWithCompanionCount()).isEqualTo(0);
    assertThat(info.getAssumePresentCount()).isEqualTo(0);
    assertThat(info.getMissingInterfaceCount()).isEqualTo(0);
    assertThat(info.getInterfaceWithSupertypesList())
        .containsExactly(
            InterfaceDetails.newBuilder()
                .setOrigin(classToType(J.class))
                .addExtendedInterface(classToType(I.class))
                .build());
  }

  @SuppressWarnings("ProtoParseWithRegistry")
  private static DesugarDepsInfo extractDesugarDeps(Path jar) throws Exception {
    try (ZipFile zip = new ZipFile(jar.toFile())) {
      ZipEntry desugarDepsEntry = zip.getEntry(Desugar.DESUGAR_DEPS_FILENAME);
      assertThat(desugarDepsEntry).isNotNull();
      return DesugarDepsInfo.parseFrom(zip.getInputStream(desugarDepsEntry));
    }
  }

  private static DesugarDeps.Type classToType(Class<?> clazz) {
    return DesugarDeps.Type.newBuilder()
        .setBinaryName(DescriptorUtils.classToBinaryName(clazz))
        .build();
  }

  private static DesugarDeps.Type classToCompanionType(Class<?> clazz) {
    return DesugarDeps.Type.newBuilder()
        .setBinaryName(DescriptorUtils.classToBinaryName(clazz) + INTERFACE_COMPANION_SUFFIX)
        .build();
  }

  @Test
  public void checkDependencyMetadata() throws Exception {
    DesugarDepsInfo info = extractDesugarDeps(desugaredWithDependencyMetadata);

    // Check expected metadata content.
    assertThat(info.getAssumePresentList())
        .containsExactly(
            Dependency.newBuilder()
                .setOrigin(classToType(A.class))
                .setTarget(classToCompanionType(I.class))
                .build(),
            Dependency.newBuilder()
                .setOrigin(classToType(B.class))
                .setTarget(classToCompanionType(J.class))
                .build(),
            Dependency.newBuilder()
                .setOrigin(classToType(C.class))
                .setTarget(classToCompanionType(K.class))
                .build());
    assertThat(info.getInterfaceWithCompanionList())
        .containsExactly(
            InterfaceWithCompanion.newBuilder()
                .setOrigin(classToType(I.class))
                .setNumDefaultMethods(1)
                .build(),
            InterfaceWithCompanion.newBuilder()
                .setOrigin(classToType(J.class))
                .setNumDefaultMethods(1)
                .build(),
            InterfaceWithCompanion.newBuilder()
                .setOrigin(classToType(K.class))
                .setNumDefaultMethods(1)
                .build());
    assertThat(info.getInterfaceWithSupertypesList())
        .containsExactly(
            InterfaceDetails.newBuilder()
                .setOrigin(classToType(J.class))
                .addExtendedInterface(classToType(I.class))
                .build());
    assertThat(info.getMissingInterfaceCount()).isEqualTo(0);
  }

  @Test
  public void checkDependencyMetadataClasspath() throws Exception {
    DesugarDepsInfo info = extractDesugarDeps(desugaredClasspathWithDependencyMetadata);

    // Check expected metadata content.
    assertThat(info.getAssumePresentList())
        .containsExactly(
            Dependency.newBuilder()
                .setOrigin(classToType(A.class))
                .setTarget(classToCompanionType(I.class))
                .build(),
            Dependency.newBuilder()
                .setOrigin(classToType(B.class))
                .setTarget(classToCompanionType(J.class))
                .build(),
            Dependency.newBuilder()
                .setOrigin(classToType(C.class))
                .setTarget(classToCompanionType(K.class))
                .build());
    assertThat(info.getInterfaceWithCompanionCount()).isEqualTo(0);
    assertThat(info.getInterfaceWithSupertypesCount()).isEqualTo(0);
    assertThat(info.getMissingInterfaceCount()).isEqualTo(0);
  }

  @Test
  public void checkDependencyMetadataMissingInterface() throws Exception {
    DesugarDepsInfo info = extractDesugarDeps(desugaredWithDependencyMetadataMissingInterface);

    // Check expected metadata content.
    assertThat(info.getAssumePresentList())
        .containsExactly(
            Dependency.newBuilder()
                .setOrigin(classToType(A.class))
                .setTarget(classToCompanionType(I.class))
                .build(),
            Dependency.newBuilder()
                .setOrigin(classToType(B.class))
                .setTarget(classToCompanionType(J.class))
                .build());
    assertThat(info.getInterfaceWithCompanionList())
        .containsExactly(
            InterfaceWithCompanion.newBuilder()
                .setOrigin(classToType(I.class))
                .setNumDefaultMethods(1)
                .build(),
            InterfaceWithCompanion.newBuilder()
                .setOrigin(classToType(J.class))
                .setNumDefaultMethods(1)
                .build());
    assertThat(info.getInterfaceWithSupertypesList())
        .containsExactly(
            InterfaceDetails.newBuilder()
                .setOrigin(classToType(J.class))
                .addExtendedInterface(classToType(I.class))
                .build());
    assertThat(info.getMissingInterfaceList())
        .containsExactly(
            Dependency.newBuilder()
                .setOrigin(classToType(C.class))
                .setTarget(classToType(K.class))
                .build());
  }

  private static void forAllClasses(Path jar, ClassVisitor classVisitor) throws Exception {
    forAllClasses(
        jar,
        classReader ->
            classReader.accept(classVisitor, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES));
  }

  private static void forAllClasses(Path jar, Consumer<ClassReader> classReader) throws Exception {

    try (JarInputStream jarInputStream =
        new JarInputStream(Files.newInputStream(jar, StandardOpenOption.READ))) {
      JarEntry entry;
      while ((entry = jarInputStream.getNextJarEntry()) != null) {
        String entryName = entry.getName();
        if (FileUtils.isClassFile(entryName)) {
          classReader.accept(new ClassReader(jarInputStream));
        }
      }
    }
  }
}
