// 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)
        // Commented out for the 1.5.13 branch as this is currently not merged.
        //.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");
    }
  }
}