// 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.naming.b72391662;

import static com.android.tools.r8.utils.dexinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;

import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.VmTestRunner;
import com.android.tools.r8.VmTestRunner.IgnoreIfVmOlderThan;
import com.android.tools.r8.naming.b72391662.subpackage.OtherPackageSuper;
import com.android.tools.r8.naming.b72391662.subpackage.OtherPackageTestClass;
import com.android.tools.r8.shaking.forceproguardcompatibility.ProguardCompatabilityTestBase;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.dexinspector.ClassSubject;
import com.android.tools.r8.utils.dexinspector.DexInspector;
import com.android.tools.r8.utils.dexinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(VmTestRunner.class)
public class B72391662 extends ProguardCompatabilityTestBase {

  private static final List<Class> CLASSES = ImmutableList.of(
      TestMain.class, Interface.class, Super.class, TestClass.class,
      OtherPackageSuper.class, OtherPackageTestClass.class);

  private void doTest_keepAll(
      Shrinker shrinker,
      String repackagePrefix,
      boolean allowAccessModification,
      boolean minify) throws Exception {
    Class mainClass = TestMain.class;
    String keep = !minify ? "-keep" : "-keep,allowobfuscation";
    List<String> config = ImmutableList.of(
        "-printmapping",
        repackagePrefix != null ? "-repackageclasses '" + repackagePrefix + "'" : "",
        allowAccessModification ? "-allowaccessmodification" : "",
        !minify ? "-dontobfuscate" : "",
        "-keep class " + mainClass.getCanonicalName() + " {",
        "  public static void main(java.lang.String[]);",
        "}",
        keep + " class " + TestClass.class.getCanonicalName() + " {",
        "  *;",
        "}",
        keep + " class " + OtherPackageTestClass.class.getCanonicalName() + " {",
        "  *;",
        "}",
        "-dontwarn java.lang.invoke.*"
    );

    AndroidApp app = runShrinkerRaw(shrinker, CLASSES, config);
    assertEquals("123451234567\nABC\n", runOnArt(app, mainClass.getCanonicalName()));

    DexInspector dexInspector =
        isR8(shrinker) ? new DexInspector(app) : new DexInspector(app, proguardMap);
    ClassSubject testClass = dexInspector.clazz(TestClass.class);
    assertThat(testClass, isPresent());

    // Test the totally unused method.
    MethodSubject staticMethod = testClass.method("void", "unused", ImmutableList.of());
    assertThat(staticMethod, isPresent());
    assertEquals(minify, staticMethod.isRenamed());
    if (isR8(shrinker)) {
      assertEquals(allowAccessModification, staticMethod.getMethod().accessFlags.isPublic());
    } else {
      assertFalse(staticMethod.getMethod().accessFlags.isPublic());
    }

    // Test an indirectly referred method.
    staticMethod = testClass.method("java.lang.String", "staticMethod", ImmutableList.of());
    assertThat(staticMethod, isPresent());
    assertEquals(minify, staticMethod.isRenamed());
    boolean publicizeCondition = isR8(shrinker) ? allowAccessModification
        : minify && repackagePrefix != null && allowAccessModification;
    assertEquals(publicizeCondition, staticMethod.getMethod().accessFlags.isPublic());
  }

  @Test
  @IgnoreIfVmOlderThan(Version.V7_0_0)
  public void test_keepAll_R8() throws Exception {
    doTest_keepAll(Shrinker.R8, "r8", true, true);
    doTest_keepAll(Shrinker.R8, "r8", true, false);
    doTest_keepAll(Shrinker.R8, "r8", false, true);
    doTest_keepAll(Shrinker.R8, "r8", false, false);
    doTest_keepAll(Shrinker.R8, null, true, true);
    doTest_keepAll(Shrinker.R8, null, true, false);
    doTest_keepAll(Shrinker.R8, null, false, true);
    doTest_keepAll(Shrinker.R8, null, false, false);
  }

  @Test
  @IgnoreIfVmOlderThan(Version.V7_0_0)
  public void test_keepAll_R8Compat() throws Exception {
    doTest_keepAll(Shrinker.R8_COMPAT, "rc", true, true);
    doTest_keepAll(Shrinker.R8_COMPAT, "rc", true, false);
    doTest_keepAll(Shrinker.R8_COMPAT, "rc", false, true);
    doTest_keepAll(Shrinker.R8_COMPAT, "rc", false, false);
    doTest_keepAll(Shrinker.R8_COMPAT, null, true, true);
    doTest_keepAll(Shrinker.R8_COMPAT, null, true, false);
    doTest_keepAll(Shrinker.R8_COMPAT, null, false, true);
    doTest_keepAll(Shrinker.R8_COMPAT, null, false, false);
  }

  @Test
  @IgnoreIfVmOlderThan(Version.V7_0_0)
  public void test_keepAll_Proguard6() throws Exception {
    doTest_keepAll(Shrinker.PROGUARD6_THEN_D8, "pg", true, true);
    doTest_keepAll(Shrinker.PROGUARD6_THEN_D8, "pg", true, false);
    doTest_keepAll(Shrinker.PROGUARD6_THEN_D8, "pg", false, true);
    doTest_keepAll(Shrinker.PROGUARD6_THEN_D8, "pg", false, false);
    doTest_keepAll(Shrinker.PROGUARD6_THEN_D8, null, true, true);
    doTest_keepAll(Shrinker.PROGUARD6_THEN_D8, null, true, false);
    doTest_keepAll(Shrinker.PROGUARD6_THEN_D8, null, false, true);
    doTest_keepAll(Shrinker.PROGUARD6_THEN_D8, null, false, false);
  }

  private void doTest_keepNonPublic(
      Shrinker shrinker,
      String repackagePrefix,
      boolean allowAccessModification,
      boolean minify) throws Exception {
    Class mainClass = TestMain.class;
    String keep = !minify ? "-keep" : "-keep,allowobfuscation";
    List<String> config = ImmutableList.of(
        "-printmapping",
        repackagePrefix != null ? "-repackageclasses '" + repackagePrefix + "'" : "",
        allowAccessModification ? "-allowaccessmodification" : "",
        !minify ? "-dontobfuscate" : "",
        "-keep class " + mainClass.getCanonicalName() + " {",
        "  public static void main(java.lang.String[]);",
        "}",
        keep + " class " + TestClass.class.getCanonicalName() + " {",
        "  !public <methods>;",
        "}",
        keep + " class " + OtherPackageTestClass.class.getCanonicalName() + " {",
        "  !public <methods>;",
        "}",
        "-dontwarn java.lang.invoke.*"
    );

    AndroidApp app = runShrinkerRaw(shrinker, CLASSES, config);
    assertEquals("123451234567\nABC\n", runOnArt(app, mainClass.getCanonicalName()));

    DexInspector dexInspector =
        isR8(shrinker) ? new DexInspector(app) : new DexInspector(app, proguardMap);
    ClassSubject testClass = dexInspector.clazz(TestClass.class);
    assertThat(testClass, isPresent());

    // Test the totally unused method.
    MethodSubject staticMethod = testClass.method("void", "unused", ImmutableList.of());
    assertThat(staticMethod, isPresent());
    assertEquals(minify, staticMethod.isRenamed());
    if (isR8(shrinker)) {
      assertEquals(allowAccessModification, staticMethod.getMethod().accessFlags.isPublic());
    } else {
      assertFalse(staticMethod.getMethod().accessFlags.isPublic());
    }

    // Test an indirectly referred method.
    staticMethod = testClass.method("java.lang.String", "staticMethod", ImmutableList.of());
    assertThat(staticMethod, isPresent());
    assertEquals(minify, staticMethod.isRenamed());
    boolean publicizeCondition = isR8(shrinker) ? allowAccessModification
        : minify && repackagePrefix != null && allowAccessModification;
    assertEquals(publicizeCondition, staticMethod.getMethod().accessFlags.isPublic());
  }

  @Test
  @IgnoreIfVmOlderThan(Version.V7_0_0)
  public void test_keepNonPublic_R8() throws Exception {
    doTest_keepNonPublic(Shrinker.R8, "r8", true, true);
    doTest_keepNonPublic(Shrinker.R8, "r8", true, false);
    doTest_keepNonPublic(Shrinker.R8, "r8", false, true);
    doTest_keepNonPublic(Shrinker.R8, "r8", false, false);
    doTest_keepNonPublic(Shrinker.R8, null, true, true);
    doTest_keepNonPublic(Shrinker.R8, null, true, false);
    doTest_keepNonPublic(Shrinker.R8, null, false, true);
    doTest_keepNonPublic(Shrinker.R8, null, false, false);
  }

  @Test
  @IgnoreIfVmOlderThan(Version.V7_0_0)
  public void test_keepNonPublic_R8Compat() throws Exception {
    doTest_keepNonPublic(Shrinker.R8_COMPAT, "rc", true, true);
    doTest_keepNonPublic(Shrinker.R8_COMPAT, "rc", true, false);
    doTest_keepNonPublic(Shrinker.R8_COMPAT, "rc", false, true);
    doTest_keepNonPublic(Shrinker.R8_COMPAT, "rc", false, false);
    doTest_keepNonPublic(Shrinker.R8_COMPAT, null, true, true);
    doTest_keepNonPublic(Shrinker.R8_COMPAT, null, true, false);
    doTest_keepNonPublic(Shrinker.R8_COMPAT, null, false, true);
    doTest_keepNonPublic(Shrinker.R8_COMPAT, null, false, false);
  }

  @Test
  @IgnoreIfVmOlderThan(Version.V7_0_0)
  public void test_keepNonPublic_Proguard6() throws Exception {
    doTest_keepNonPublic(Shrinker.PROGUARD6_THEN_D8, "pg", true, true);
    doTest_keepNonPublic(Shrinker.PROGUARD6_THEN_D8, "pg", true, false);
    doTest_keepNonPublic(Shrinker.PROGUARD6_THEN_D8, "pg", false, true);
    doTest_keepNonPublic(Shrinker.PROGUARD6_THEN_D8, "pg", false, false);
    doTest_keepNonPublic(Shrinker.PROGUARD6_THEN_D8, null, true, true);
    doTest_keepNonPublic(Shrinker.PROGUARD6_THEN_D8, null, true, false);
    doTest_keepNonPublic(Shrinker.PROGUARD6_THEN_D8, null, false, true);
    doTest_keepNonPublic(Shrinker.PROGUARD6_THEN_D8, null, false, false);
  }

  private void doTest_keepPublic(
      Shrinker shrinker,
      String repackagePrefix,
      boolean allowAccessModification,
      boolean minify) throws Exception {
    Class mainClass = TestMain.class;
    String keep = !minify ? "-keep" : "-keep,allowobfuscation";
    Iterable<String> config = ImmutableList.of(
        "-printmapping",
        repackagePrefix != null ? "-repackageclasses '" + repackagePrefix + "'" : "",
        allowAccessModification ? "-allowaccessmodification" : "",
        !minify ? "-dontobfuscate" : "",
        "-keep class " + mainClass.getCanonicalName() + " {",
        "  public static void main(java.lang.String[]);",
        "}",
        keep + " class " + TestClass.class.getCanonicalName() + " {",
        "  public <methods>;",
        "}",
        keep + " class " + OtherPackageTestClass.class.getCanonicalName() + " {",
        "  public <methods>;",
        "}",
        "-dontwarn java.lang.invoke.*"
    );
    if (isR8(shrinker)) {
      config = Iterables.concat(config, ImmutableList.of(
          "-neverinline class " + TestClass.class.getCanonicalName() + " {",
          "  * staticMethod();",
          "}"
      ));
    }

    AndroidApp app = runShrinkerRaw(shrinker, CLASSES, config);
    assertEquals("123451234567\nABC\n", runOnArt(app, mainClass.getCanonicalName()));

    DexInspector dexInspector =
        isR8(shrinker) ? new DexInspector(app) : new DexInspector(app, proguardMap);
    ClassSubject testClass = dexInspector.clazz(TestClass.class);
    assertThat(testClass, isPresent());

    // Test the totally unused method.
    MethodSubject staticMethod = testClass.method("void", "unused", ImmutableList.of());
    assertThat(staticMethod, not(isPresent()));

    // Test an indirectly referred method.
    staticMethod = testClass.method("java.lang.String", "staticMethod", ImmutableList.of());
    assertThat(staticMethod, isPresent());
    assertEquals(minify, staticMethod.isRenamed());
    boolean publicizeCondition = isR8(shrinker) ? allowAccessModification
        : minify && repackagePrefix != null && allowAccessModification;
    assertEquals(publicizeCondition, staticMethod.getMethod().accessFlags.isPublic());
  }

  @Test
  @IgnoreIfVmOlderThan(Version.V7_0_0)
  public void test_keepPublic_R8() throws Exception {
    doTest_keepPublic(Shrinker.R8, "r8", true, true);
    doTest_keepPublic(Shrinker.R8, "r8", true, false);
    doTest_keepPublic(Shrinker.R8, "r8", false, true);
    doTest_keepPublic(Shrinker.R8, "r8", false, false);
    doTest_keepPublic(Shrinker.R8, null, true, true);
    doTest_keepPublic(Shrinker.R8, null, true, false);
    doTest_keepPublic(Shrinker.R8, null, false, true);
    doTest_keepPublic(Shrinker.R8, null, false, false);
  }

  @Test
  @IgnoreIfVmOlderThan(Version.V7_0_0)
  public void test_keepPublic_R8Compat() throws Exception {
    doTest_keepPublic(Shrinker.R8_COMPAT, "rc", true, true);
    doTest_keepPublic(Shrinker.R8_COMPAT, "rc", true, false);
    doTest_keepPublic(Shrinker.R8_COMPAT, "rc", false, true);
    doTest_keepPublic(Shrinker.R8_COMPAT, "rc", false, false);
    doTest_keepPublic(Shrinker.R8_COMPAT, null, true, true);
    doTest_keepPublic(Shrinker.R8_COMPAT, null, true, false);
    doTest_keepPublic(Shrinker.R8_COMPAT, null, false, true);
    doTest_keepPublic(Shrinker.R8_COMPAT, null, false, false);
  }

  @Test
  @IgnoreIfVmOlderThan(Version.V7_0_0)
  public void test_keepPublic_Proguard6() throws Exception {
    doTest_keepPublic(Shrinker.PROGUARD6_THEN_D8, "pg", true, true);
    doTest_keepPublic(Shrinker.PROGUARD6_THEN_D8, "pg", true, false);
    doTest_keepPublic(Shrinker.PROGUARD6_THEN_D8, "pg", false, true);
    doTest_keepPublic(Shrinker.PROGUARD6_THEN_D8, "pg", false, false);
    doTest_keepPublic(Shrinker.PROGUARD6_THEN_D8, null, true, true);
    doTest_keepPublic(Shrinker.PROGUARD6_THEN_D8, null, true, false);
    doTest_keepPublic(Shrinker.PROGUARD6_THEN_D8, null, false, true);
    doTest_keepPublic(Shrinker.PROGUARD6_THEN_D8, null, false, false);
  }
}
