// Copyright (c) 2023, 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.keepanno;

import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.keepanno.annotations.FieldAccessFlags;
import com.android.tools.r8.keepanno.annotations.KeepItemKind;
import com.android.tools.r8.keepanno.annotations.KeepTarget;
import com.android.tools.r8.keepanno.annotations.MemberAccessFlags;
import com.android.tools.r8.keepanno.annotations.MethodAccessFlags;
import com.android.tools.r8.keepanno.annotations.UsesReflection;
import com.android.tools.r8.utils.AndroidApiLevel;
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.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  static final String EXPECTED =
      StringUtils.lines(
          // Field targets.
          "packagePrivateField",
          "protectedField",
          "publicField",
          // Method targets.
          "privateMethod",
          "protectedMethod",
          "publicMethod",
          // Member field targets.
          "packagePrivateField",
          "privateField",
          // Member method targets.
          "packagePrivateMethod",
          "privateMethod");

  private final TestParameters parameters;

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withDefaultRuntimes().withApiLevel(AndroidApiLevel.B).build();
  }

  public KeepAccessVisibilityFlagsTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  @Test
  public void testReference() throws Exception {
    testForRuntime(parameters)
        .addProgramClasses(getInputClasses())
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
  }

  @Test
  public void testWithRuleExtraction() throws Exception {
    testForR8(parameters.getBackend())
        .enableExperimentalKeepAnnotations()
        .addProgramClasses(getInputClasses())
        .addKeepMainRule(TestClass.class)
        .setMinApi(parameters)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED)
        .inspect(this::checkOutput);
  }

  public List<Class<?>> getInputClasses() {
    return ImmutableList.of(
        TestClass.class,
        A.class,
        FieldRuleTarget.class,
        MethodRuleTarget.class,
        MemberRuleTarget.class);
  }

  private static List<String> allMembers =
      ImmutableList.of(
          "publicField",
          "protectedField",
          "packagePrivateField",
          "privateField",
          "publicMethod",
          "protectedMethod",
          "packagePrivateMethod",
          "privateMethod");

  private void checkOutput(CodeInspector inspector) {
    assertPresent(
        inspector, FieldRuleTarget.class, "publicField", "protectedField", "packagePrivateField");
    assertPresent(
        inspector, MethodRuleTarget.class, "publicMethod", "protectedMethod", "privateMethod");
    assertPresent(
        inspector,
        MemberRuleTarget.class,
        "packagePrivateField",
        "privateField",
        "packagePrivateMethod",
        "privateMethod");
  }

  private void assertPresent(CodeInspector inspector, Class<?> clazz, String... members) {
    ClassSubject subject = inspector.clazz(clazz);
    assertThat(subject, isPresent());
    Set<String> expectedPresent = ImmutableSet.copyOf(members);
    for (String member : allMembers) {
      if (member.endsWith("Field")) {
        assertThat(
            subject.uniqueFieldWithOriginalName(member),
            expectedPresent.contains(member) ? isPresent() : isAbsent());
      } else {
        assertThat(
            subject.uniqueMethodWithOriginalName(member),
            expectedPresent.contains(member) ? isPresent() : isAbsent());
      }
    }
  }

  abstract static class FieldRuleTarget {
    public String publicField = "public";
    protected String protectedField = "protected";
    private String privateField = "private";
    String packagePrivateField = "package-private";

    public void publicMethod() {}

    protected void protectedMethod() {}

    private void privateMethod() {}

    void packagePrivateMethod() {}
  }

  abstract static class MethodRuleTarget {
    public String publicField = "public";
    protected String protectedField = "protected";
    private String privateField = "private";
    String packagePrivateField = "package-private";

    public void publicMethod() {}

    protected void protectedMethod() {}

    private void privateMethod() {}

    void packagePrivateMethod() {}
  }

  abstract static class MemberRuleTarget {
    public String publicField = "public";
    protected String protectedField = "protected";
    private String privateField = "private";
    String packagePrivateField = "package-private";

    public void publicMethod() {}

    protected void protectedMethod() {}

    private void privateMethod() {}

    void packagePrivateMethod() {}
  }

  static class A {

    @UsesReflection({
      @KeepTarget(
          kind = KeepItemKind.CLASS_AND_MEMBERS,
          classConstant = FieldRuleTarget.class,
          fieldAccess = {FieldAccessFlags.NON_PRIVATE}),
      @KeepTarget(
          kind = KeepItemKind.CLASS_AND_MEMBERS,
          classConstant = MethodRuleTarget.class,
          methodAccess = {MethodAccessFlags.NON_PACKAGE_PRIVATE}),
      @KeepTarget(
          kind = KeepItemKind.CLASS_AND_MEMBERS,
          classConstant = MemberRuleTarget.class,
          memberAccess = {MemberAccessFlags.PACKAGE_PRIVATE, MemberAccessFlags.PRIVATE}),
    })
    void foo() {
      // Print all non-private fields.
      {
        List<String> nonPrivateFields = new ArrayList<>();
        for (Field field : FieldRuleTarget.class.getDeclaredFields()) {
          int mod = field.getModifiers();
          if (!Modifier.isPrivate(mod)) {
            nonPrivateFields.add(field.getName());
          }
        }
        printSorted(nonPrivateFields);
      }
      // Print all non-package-private methods.
      {
        List<String> nonPackagePrivateMethods = new ArrayList<>();
        for (Method method : MethodRuleTarget.class.getDeclaredMethods()) {
          int mod = method.getModifiers();
          if (Modifier.isPublic(mod) || Modifier.isProtected(mod) || Modifier.isPrivate(mod)) {
            nonPackagePrivateMethods.add(method.getName());
          }
        }
        printSorted(nonPackagePrivateMethods);
      }
      // Print all private and package-private members.
      {
        List<String> privateOrPackagePrivateFields = new ArrayList<>();
        for (Field field : MemberRuleTarget.class.getDeclaredFields()) {
          int mod = field.getModifiers();
          if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod)) {
            privateOrPackagePrivateFields.add(field.getName());
          }
        }
        printSorted(privateOrPackagePrivateFields);
      }
      {
        List<String> privateOrPackagePrivateMethods = new ArrayList<>();
        for (Method method : MemberRuleTarget.class.getDeclaredMethods()) {
          int mod = method.getModifiers();
          if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod)) {
            privateOrPackagePrivateMethods.add(method.getName());
          }
        }
        printSorted(privateOrPackagePrivateMethods);
      }
    }

    // The order of methods and fields is different on stock JDKs depending on linux or windows
    // hosts. It is also different once compiled to DEX where the pools are split. Sort the
    // names lexicographically to avoid differences in output.
    private static void printSorted(List<String> strings) {
      strings.sort(String::compareTo);
      for (String string : strings) {
        System.out.println(string);
      }
    }
  }

  static class TestClass {

    public static void main(String[] args) throws Exception {
      new A().foo();
    }
  }
}
