// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

interface B112452064SuperInterface1 {
  void foo();
}

interface B112452064SuperInterface2 {
  void bar();
}

interface B112452064SubInterface extends B112452064SuperInterface1, B112452064SuperInterface2 {
}

class B112452064TestMain {

  static void bazSuper1(B112452064SuperInterface1 instance) {
    instance.foo();
  }

  static void bazSub(B112452064SubInterface instance) {
    instance.foo();
  }

  public static void main(String[] args) {
    bazSuper1(new B112452064SuperInterface1() {
      @Override
      public void foo() {
        System.out.println("Anonymous1::foo");
      }
    });
    bazSub(new B112452064SubInterface() {
      @Override
      public void foo() {
        System.out.println("Anonymous2::foo");
      }
      @Override
      public void bar() {
        System.out.println("Anonymous2::bar");
      }
    });
  }
}

@RunWith(Parameterized.class)
public class ParameterTypeTest extends TestBase {

  private final boolean enableArgumentRemoval;
  private final TestParameters parameters;

  @Parameters(name = "{1}, argument removal: {0}")
  public static List<Object[]> data() {
    return buildParameters(BooleanUtils.values(), getTestParameters().withAllRuntimes().build());
  }

  public ParameterTypeTest(boolean enableArgumentRemoval, TestParameters parameters) {
    this.enableArgumentRemoval = enableArgumentRemoval;
    this.parameters = parameters;
  }

  @Test
  public void test_fromJavacWithVerticalClassMerging() throws Exception {
    test_fromJavac(false, true);
  }

  @Test
  public void test_fromJavacWithVerticalClassMergingAndUnusedInterfaceRemoval() throws Exception {
    test_fromJavac(true, true);
  }

  @Test
  public void test_fromJavacWithoutVerticalClassMerging() throws Exception {
    test_fromJavac(false, false);
  }

  private void test_fromJavac(
      boolean enableUnusedInterfaceRemoval, boolean enableVerticalClassMerging) throws Exception {
    String mainName = B112452064TestMain.class.getCanonicalName();
    ProcessResult javaResult = ToolHelper.runJava(ToolHelper.getClassPathForTests(), mainName);
    assertEquals(0, javaResult.exitCode);
    assertThat(javaResult.stdout, containsString("Anonymous"));
    assertThat(javaResult.stdout, containsString("::foo"));
    assertEquals(-1, javaResult.stderr.indexOf("ClassNotFoundException"));

    CodeInspector inspector =
        testForR8(parameters.getBackend())
            .addProgramFiles(
                ToolHelper.getClassFilesForTestDirectory(
                    ToolHelper.getPackageDirectoryForTestPackage(
                        B112452064TestMain.class.getPackage()),
                    path -> path.getFileName().toString().startsWith("B112452064")))
            .addKeepMainRule(B112452064TestMain.class)
            .addOptionsModification(
                options -> {
                  options.enableInlining = false;
                  options.enableUnusedInterfaceRemoval = enableUnusedInterfaceRemoval;
                  options.enableVerticalClassMerging = enableVerticalClassMerging;
                })
            .setMinApi(parameters.getRuntime())
            .compile()
            .run(parameters.getRuntime(), B112452064TestMain.class)
            .assertSuccessWithOutput(javaResult.stdout)
            .assertStderrMatches(not(containsString("ClassNotFoundException")))
            .inspector();

    ClassSubject superInterface1 = inspector.clazz(B112452064SuperInterface1.class);
    assertThat(superInterface1, isPresentAndRenamed());
    MethodSubject foo = superInterface1.uniqueMethodWithName("foo");
    assertThat(foo, not(isPresent()));
    ClassSubject superInterface2 = inspector.clazz(B112452064SuperInterface2.class);
    if (enableVerticalClassMerging) {
      assertThat(superInterface2, not(isPresent()));
    } else {
      assertThat(superInterface2, isPresentAndRenamed());
    }
    MethodSubject bar = superInterface2.uniqueMethodWithName("bar");
    assertThat(bar, not(isPresent()));
    ClassSubject subInterface = inspector.clazz(B112452064SubInterface.class);
    if (enableUnusedInterfaceRemoval) {
      assertThat(subInterface, not(isPresent()));
    } else {
      assertThat(subInterface, isPresent());
      assertThat(subInterface, isPresentAndRenamed());
    }
  }

  @Test
  public void test_brokenTypeHierarchy_singleInterface() throws Exception {
    JasminBuilder jasminBuilder = new JasminBuilder();
    // interface SuperInterface {
    //   void foo();
    // }
    ClassBuilder sup = jasminBuilder.addInterface("SuperInterface");
    MethodSignature foo = sup.addAbstractMethod("foo", ImmutableList.of(), "V");
    // interface SubInterface extends SuperInterface
    ClassBuilder sub = jasminBuilder.addInterface("SubInterface", sup.name);

    // class Foo implements SuperInterface /* supposed to implement SubInterface */
    ClassBuilder impl = jasminBuilder.addClass("Foo", "java/lang/Object", sup.name);
    impl.addDefaultConstructor();
    impl.addVirtualMethod(foo.name, ImmutableList.of(), "V",
        ".limit locals 2",
        ".limit stack 2",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "ldc \"" + foo.name + "\"",
        "invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
        "return");

    // class TestMain {
    //   static bar(SubInterface instance) {
    //     // instance.foo();
    //   }
    //   public static void main(String[] args) {
    //     // ART verifies the argument (Foo) is an instance of the parameter type (SubInterface).
    //     bar(new Foo());
    //   }
    // }
    ClassBuilder mainClass = jasminBuilder.addClass("Main");
    MethodSignature bar =
        mainClass.addStaticMethod("bar", ImmutableList.of(sub.getDescriptor()), "V",
            ".limit locals 2",
            ".limit stack 2",
            "getstatic java/lang/System/out Ljava/io/PrintStream;",
            "ldc \"" + "bar" + "\"",
            "invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
            "return");
    mainClass.addMainMethod(
        ".limit locals 1",
        ".limit stack 2",
        "new " + impl.name,
        "dup",
        "invokespecial " + impl.name + "/<init>()V",
        "invokestatic " + mainClass.name + "/bar(" + sub.getDescriptor() + ")V",
        "return");

    final String mainClassName = mainClass.name;
    String proguardConfig = keepMainProguardConfiguration(mainClassName, false, false);

    // Run input program on java.
    Path outputDirectory = temp.newFolder().toPath();
    jasminBuilder.writeClassFiles(outputDirectory);
    ProcessResult javaResult = ToolHelper.runJava(outputDirectory, mainClassName);
    assertEquals(0, javaResult.exitCode);
    assertThat(javaResult.stdout, containsString(bar.name));
    assertEquals(-1, javaResult.stderr.indexOf("ClassNotFoundException"));

    AndroidApp processedApp =
        compileWithR8(
            jasminBuilder.build(),
            proguardConfig,
            options -> {
              // Disable inlining to avoid the (short) tested method from being inlined and removed.
              options.enableInlining = false;
              options.enableArgumentRemoval = enableArgumentRemoval;
            });

    // Run processed (output) program on ART
    ProcessResult artResult = runOnArtRaw(processedApp, mainClassName);
    assertEquals(0, artResult.exitCode);
    assertThat(artResult.stdout, containsString(bar.name));
    assertEquals(-1, artResult.stderr.indexOf("ClassNotFoundException"));

    CodeInspector inspector = new CodeInspector(processedApp);
    ClassSubject subSubject = inspector.clazz(sub.name);
    assertNotEquals(enableArgumentRemoval, subSubject.isPresent());
  }

  @Test
  public void test_brokenTypeHierarchy_arrayType() throws Exception {
    JasminBuilder jasminBuilder = new JasminBuilder();
    // interface SuperInterface {
    //   void foo();
    // }
    ClassBuilder sup = jasminBuilder.addInterface("SuperInterface");
    MethodSignature foo = sup.addAbstractMethod("foo", ImmutableList.of(), "V");
    // interface SubInterface extends SuperInterface
    ClassBuilder sub = jasminBuilder.addInterface("SubInterface", sup.name);

    // class Foo implements SuperInterface /* supposed to implement SubInterface */
    ClassBuilder impl = jasminBuilder.addClass("Foo", "java/lang/Object", sup.name);
    impl.addDefaultConstructor();
    impl.addVirtualMethod(foo.name, ImmutableList.of(), "V",
        ".limit locals 2",
        ".limit stack 2",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "ldc \"" + foo.name + "\"",
        "invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
        "return");

    // class TestMain {
    //   static bar(SubInterface[] array) {
    //     // instance.foo();
    //   }
    //   public static void main(String[] args) {
    //     // ART verifies the argument (Foo) is an instance of the parameter type (SubInterface).
    //     bar(new Foo());
    //   }
    // }
    ClassBuilder mainClass = jasminBuilder.addClass("Main");
    MethodSignature bar =
        mainClass.addStaticMethod("bar", ImmutableList.of("[" + sub.getDescriptor()), "V",
            ".limit locals 2",
            ".limit stack 2",
            "getstatic java/lang/System/out Ljava/io/PrintStream;",
            "ldc \"" + "bar" + "\"",
            "invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
            "return");
    mainClass.addMainMethod(
        ".limit locals 1",
        ".limit stack 2",
        "iconst_1",
        "anewarray " + impl.name,
        "invokestatic " + mainClass.name + "/bar(" + "[" + sub.getDescriptor() + ")V",
        "return");

    final String mainClassName = mainClass.name;
    String proguardConfig = keepMainProguardConfiguration(mainClassName, false, false);

    // Run input program on java.
    Path outputDirectory = temp.newFolder().toPath();
    jasminBuilder.writeClassFiles(outputDirectory);
    ProcessResult javaResult = ToolHelper.runJava(outputDirectory, mainClassName);
    assertEquals(0, javaResult.exitCode);
    assertThat(javaResult.stdout, containsString(bar.name));
    assertEquals(-1, javaResult.stderr.indexOf("ClassNotFoundException"));

    AndroidApp processedApp =
        compileWithR8(
            jasminBuilder.build(),
            proguardConfig,
            options -> {
              // Disable inlining to avoid the (short) tested method from being inlined and removed.
              options.enableInlining = false;
              options.enableArgumentRemoval = enableArgumentRemoval;
            });

    // Run processed (output) program on ART
    ProcessResult artResult = runOnArtRaw(processedApp, mainClassName);
    if (enableArgumentRemoval) {
      assertEquals(0, artResult.exitCode);
    } else {
      assertNotEquals(0, artResult.exitCode);

      DexVm.Version currentVersion = ToolHelper.getDexVm().getVersion();
      String errorMessage =
          currentVersion.isNewerThan(Version.V4_4_4)
              ? "type Precise Reference: Foo[] but expected Reference: SubInterface[]"
              : "[LFoo; is not instance of [LSubInterface;";
      assertThat(artResult.stderr, containsString(errorMessage));
    }

    assertEquals(-1, artResult.stderr.indexOf("ClassNotFoundException"));

    CodeInspector inspector = new CodeInspector(processedApp);
    ClassSubject subSubject = inspector.clazz(sub.name);
    assertNotEquals(enableArgumentRemoval, subSubject.isPresent());
  }

  @Test
  public void test_brokenTypeHierarchy_doubleInterfaces() throws Exception {
    JasminBuilder jasminBuilder = new JasminBuilder();
    // interface SuperInterface1 {
    //   void foo();
    // }
    ClassBuilder sup1 = jasminBuilder.addInterface("SuperInterface1");
    MethodSignature foo = sup1.addAbstractMethod("foo", ImmutableList.of(), "V");
    // interface SuperInterface2 {
    //   void bar();
    // }
    ClassBuilder sup2 = jasminBuilder.addInterface("SuperInterface2");
    MethodSignature bar = sup1.addAbstractMethod("bar", ImmutableList.of(), "V");
    // interface SubInterface extends SuperInterface1, SuperInterface2
    ClassBuilder sub = jasminBuilder.addInterface("SubInterface", sup1.name, sup2.name);

    // class Foo implements SuperInterface1, SuperInterface2
    //   /* supposed to implement SubInterface */
    ClassBuilder impl = jasminBuilder.addClass("Foo", "java/lang/Object", sup1.name, sup2.name);
    impl.addDefaultConstructor();
    impl.addVirtualMethod(foo.name, ImmutableList.of(), "V",
        ".limit locals 2",
        ".limit stack 2",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "ldc \"" + foo.name + "\"",
        "invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
        "return");
    impl.addVirtualMethod(bar.name, ImmutableList.of(), "V",
        ".limit locals 2",
        ".limit stack 2",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "ldc \"" + bar.name + "\"",
        "invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
        "return");

    // class TestMain {
    //   static bar(SubInterface instance) {
    //     // instance.foo();
    //   }
    //   public static void main(String[] args) {
    //     // ART verifies the argument (Foo) is an instance of the parameter type (SubInterface).
    //     bar(new Foo());
    //   }
    // }
    ClassBuilder mainClass = jasminBuilder.addClass("Main");
    MethodSignature baz =
        mainClass.addStaticMethod("baz", ImmutableList.of(sub.getDescriptor()), "V",
            ".limit locals 2",
            ".limit stack 2",
            "getstatic java/lang/System/out Ljava/io/PrintStream;",
            "ldc \"" + "baz" + "\"",
            "invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
            "return");
    mainClass.addMainMethod(
        ".limit locals 1",
        ".limit stack 2",
        "new " + impl.name,
        "dup",
        "invokespecial " + impl.name + "/<init>()V",
        "invokestatic " + mainClass.name + "/baz(" + sub.getDescriptor() + ")V",
        "return");

    final String mainClassName = mainClass.name;
    String proguardConfig = keepMainProguardConfiguration(mainClassName, false, false);

    // Run input program on java.
    Path outputDirectory = temp.newFolder().toPath();
    jasminBuilder.writeClassFiles(outputDirectory);
    ProcessResult javaResult = ToolHelper.runJava(outputDirectory, mainClassName);
    assertEquals(0, javaResult.exitCode);
    assertThat(javaResult.stdout, containsString(baz.name));
    assertEquals(-1, javaResult.stderr.indexOf("ClassNotFoundException"));

    AndroidApp processedApp =
        compileWithR8(
            jasminBuilder.build(),
            proguardConfig,
            options -> {
              // Disable inlining to avoid the (short) tested method from being inlined and removed.
              options.enableInlining = false;
              options.enableArgumentRemoval = enableArgumentRemoval;
            });

    // Run processed (output) program on ART
    ProcessResult artResult = runOnArtRaw(processedApp, mainClassName);
    assertEquals(0, artResult.exitCode);
    assertThat(artResult.stdout, containsString(baz.name));
    assertEquals(javaResult.stdout, artResult.stdout);
    assertEquals(-1, artResult.stderr.indexOf("ClassNotFoundException"));

    CodeInspector inspector = new CodeInspector(processedApp);
    ClassSubject subSubject = inspector.clazz(sub.name);
    assertNotEquals(enableArgumentRemoval, subSubject.isPresent());
  }
}
