// 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.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;
import org.junit.runners.Parameterized.Parameters;

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

  enum Expect {
    STATICS_ONLY,
    NON_STATICS_ONLY,
    BOTH_STATICS_AND_NON_STATICS
  }

  private final Backend backend;
  private static final int PPP =
      Constants.ACC_PUBLIC | Constants.ACC_PROTECTED | Constants.ACC_PRIVATE;

  @Parameters(name = "Backend: {0}")
  public static Backend[] data() {
    return Backend.values();
  }

  public AccessFlagsCombinationsTest(Backend backend) {
    assertEquals(7, PPP);
    this.backend = backend;
  }

  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(backend)
        .addInnerClasses(AccessFlagsCombinationsTest.class)
        .addKeepMainRule(TestClass.class)
        .addKeepRules(keepRules)
        .compile()
        .inspect(inspector)
        .run(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");
    }
  }
}