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

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.dex.Constants;
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 java.util.List;
import java.util.function.Consumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  enum Expect {
    STATICS_ONLY,
    NON_STATICS_ONLY,
    BOTH_STATICS_AND_NON_STATICS
  }

  private final TestParameters parameters;
  private static final int PPP =
      Constants.ACC_PUBLIC | Constants.ACC_PROTECTED | Constants.ACC_PRIVATE;

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

  public AccessFlagsCombinationsTest(TestParameters parameters) {
    assertEquals(7, PPP);
    this.parameters = parameters;
  }

  private void checkKeptMembers(CodeInspector inspector, Integer flags, Expect expect) {
    ClassSubject classSubject = inspector.clazz(TestClass.class);

    boolean includeStatic =
        expect == Expect.STATICS_ONLY || expect == Expect.BOTH_STATICS_AND_NON_STATICS;
    boolean includeNonStatic =
        expect == Expect.NON_STATICS_ONLY || expect == Expect.BOTH_STATICS_AND_NON_STATICS;


    boolean includePublic = (flags & PPP) == 0 || (flags & Constants.ACC_PUBLIC) != 0;
    boolean includeProtected = (flags & PPP) == 0 || (flags & Constants.ACC_PROTECTED) != 0;
    boolean includePrivate = (flags & PPP) == 0 || (flags & Constants.ACC_PRIVATE) != 0;
    boolean includePackagePrivate = (flags & PPP) == 0;

    assertEquals(
        includePublic && includeNonStatic,
        classSubject.uniqueMethodWithName("publicMethod").isPresent());
    assertEquals(
        includeProtected && includeNonStatic,
        classSubject.uniqueMethodWithName("protectedMethod").isPresent());
    assertEquals(
        includePrivate && includeNonStatic,
        classSubject.uniqueMethodWithName("privateMethod").isPresent());
    assertEquals(
        includePackagePrivate && includeNonStatic,
        classSubject.uniqueMethodWithName("packagePrivateMethod").isPresent());
    assertEquals(
        includePublic && includeStatic,
        classSubject.uniqueMethodWithName("publicStaticMethod").isPresent());
    assertEquals(
        includeProtected && includeStatic,
        classSubject.uniqueMethodWithName("protectedStaticMethod").isPresent());
    assertEquals(
        includePrivate && includeStatic,
        classSubject.uniqueMethodWithName("privateStaticMethod").isPresent());
    assertEquals(
        includePackagePrivate && includeStatic,
        classSubject.uniqueMethodWithName("packagePrivateStaticMethod").isPresent());
    assertEquals(
        includePublic && includeNonStatic,
        classSubject.uniqueFieldWithName("publicField").isPresent());
    assertEquals(
        includeProtected && includeNonStatic,
        classSubject.uniqueFieldWithName("protectedField").isPresent());
    assertEquals(
        includePrivate && includeNonStatic,
        classSubject.uniqueFieldWithName("privateField").isPresent());
    assertEquals(
        includePackagePrivate && includeNonStatic,
        classSubject.uniqueFieldWithName("packagePrivateField").isPresent());
    assertEquals(
        includePublic && includeStatic,
        classSubject.uniqueFieldWithName("publicStaticField").isPresent());
    assertEquals(
        includeProtected && includeStatic,
        classSubject.uniqueFieldWithName("protectedStaticField").isPresent());
    assertEquals(
        includePrivate && includeStatic,
        classSubject.uniqueFieldWithName("privateStaticField").isPresent());
    assertEquals(
        includePackagePrivate && includeStatic,
        classSubject.uniqueFieldWithName("packagePrivateStaticField").isPresent());
  }

  public void runTest(List<String> keepRules, Consumer<CodeInspector> inspector) throws Exception {
    String expectedOutput = StringUtils.lines("Hello, world");
    testForR8(parameters.getBackend())
        .addInnerClasses(AccessFlagsCombinationsTest.class)
        .addKeepMainRule(TestClass.class)
        .addKeepRules(keepRules)
        .setMinApi(parameters.getRuntime())
        .compile()
        .inspect(inspector)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(expectedOutput);
  }

  private String flagString(int flags) {
    return new StringBuilder()
        .append((flags & Constants.ACC_PUBLIC) != 0 ? " public" : "")
        .append((flags & Constants.ACC_PROTECTED) != 0 ? " protected" : "")
        .append((flags & Constants.ACC_PRIVATE) != 0 ? " private" : "")
        .toString();
  }

  @Test
  public void testImplicitBothStaticAndNonStaticMembers() throws Exception {
    for (int flags = 0; flags <= PPP; flags++) {
      Integer finalFlags = flags;
      runTest(
          ImmutableList.of("-keep class **.*TestClass {" + flagString(flags) + " *; }"),
          inspector ->
              checkKeptMembers(inspector, finalFlags, Expect.BOTH_STATICS_AND_NON_STATICS));
    }
  }

  @Test
  public void testExplicitNotStaticMembers() throws Exception {
    for (int flags = 0; flags <= PPP; flags++) {
      Integer finalFlags = flags;
      runTest(
          ImmutableList.of("-keep class **.*TestClass { !static" + flagString(flags) + " *; }"),
          inspector -> checkKeptMembers(inspector, finalFlags, Expect.NON_STATICS_ONLY));
    }
  }

  @Test
  public void testStaticMembers() throws Exception {
    for (int flags = 0; flags <= PPP; flags++) {
      Integer finalFlags = flags | Constants.ACC_STATIC;
      runTest(
          ImmutableList.of("-keep class **.*TestClass { static" + flagString(flags) + " *; }"),
          inspector -> checkKeptMembers(inspector, finalFlags, Expect.STATICS_ONLY));
    }
  }

  static class TestClass {
    public static int publicStaticField;
    protected static int protectedStaticField;
    private static int privateStaticField;
    static int packagePrivateStaticField;
    public int publicField;
    protected int protectedField;
    private int privateField;
    int packagePrivateField;

    public static void publicStaticMethod() {

    }

    protected static void protectedStaticMethod() {

    }

    private static void privateStaticMethod() {

    }

    static void packagePrivateStaticMethod() {

    }

    public void publicMethod() {

    }

    protected void protectedMethod() {

    }

    private void privateMethod() {

    }

    void packagePrivateMethod() {

    }

    public static void main(String[] args) {
      System.out.println("Hello, world");
    }
  }
}