// 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.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.errors.Unreachable;
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.ProguardCompatibilityTestBase;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.StringUtils;
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 com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class B72391662 extends ProguardCompatibilityTestBase {

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

  private final Shrinker shrinker;
  private final String repackagePrefix;
  private final boolean allowAccessModification;
  private final boolean minify;

  @Parameterized.Parameters(name = "Shrinker: {0}, Prefix: {1}, AllowAccessMod: {2}, Minify: {3}")
  public static Collection<Object[]> data() {
    List<Object[]> result = new ArrayList<>();
    for (Shrinker shrinker :
        new Shrinker[] {
          Shrinker.R8,
          Shrinker.R8_COMPAT,
          Shrinker.PROGUARD6_THEN_D8,
          Shrinker.R8_CF,
          Shrinker.R8_COMPAT_CF
        }) {
      for (boolean useRepackagePrefix : new boolean[] {false, true}) {
        String repackagePrefix;
        if (useRepackagePrefix) {
          switch (shrinker) {
            case R8:
              repackagePrefix = "r8";
              break;
            case R8_COMPAT:
              repackagePrefix = "rc";
              break;
            case PROGUARD6_THEN_D8:
              repackagePrefix = "pg";
              break;
            case R8_CF:
              repackagePrefix = "r8cf";
              break;
            case R8_COMPAT_CF:
              repackagePrefix = "rccf";
              break;
            default:
              assert false;
              throw new Unreachable();
          }
        } else {
          repackagePrefix = null;
        }
        for (boolean allowAccessModification : new boolean[] {false, true}) {
          for (boolean minify : new boolean[] {false, true}) {
            result.add(new Object[] {shrinker, repackagePrefix, allowAccessModification, minify});
          }
        }
      }
    }
    return result;
  }

  public B72391662(
      Shrinker shrinker, String repackagePrefix, boolean allowAccessModification, boolean minify) {
    this.shrinker = shrinker;
    this.repackagePrefix = repackagePrefix;
    this.allowAccessModification = allowAccessModification;
    this.minify = minify;
  }

  private static boolean vmVersionIgnored() {
    return !ToolHelper.getDexVm().getVersion().isAtLeast(Version.V7_0_0);
  }

  @Test
  public void test_keepAll() throws Exception {
    Assume.assumeFalse(shrinker.generatesDex() && vmVersionIgnored());
    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 = runShrinker(shrinker, CLASSES, config);
    assertEquals(
        StringUtils.withNativeLineSeparator("123451234567\nABC\n"),
        runOnVM(app, mainClass.getCanonicalName(), shrinker.toBackend()));

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

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

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

  @Test
  public void test_keepNonPublic() throws Exception {
    Assume.assumeFalse(shrinker.generatesDex() && vmVersionIgnored());
    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 = runShrinker(shrinker, CLASSES, config);
    assertEquals(
        StringUtils.withNativeLineSeparator("123451234567\nABC\n"),
        runOnVM(app, mainClass.getCanonicalName(), shrinker.toBackend()));

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

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

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

  @Test
  public void test_keepPublic() throws Exception {
    Assume.assumeFalse(shrinker.generatesDex() && vmVersionIgnored());
    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 (shrinker.isR8()) {
      config =
          Iterables.concat(
              config,
              ImmutableList.of(
                  "-assumemayhavesideeffects class " + TestClass.class.getCanonicalName() + " {",
                  "  * staticMethod();",
                  "}",
                  "-neverinline class " + TestClass.class.getCanonicalName() + " {",
                  "  * staticMethod();",
                  "}"));
    }

    AndroidApp app = runShrinker(shrinker, CLASSES, config);
    assertEquals(
        StringUtils.withNativeLineSeparator("123451234567\nABC\n"),
        runOnVM(app, mainClass.getCanonicalName(), shrinker.toBackend()));

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

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

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