// 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.accessrelaxation;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.accessrelaxation.privateinstance.Base;
import com.android.tools.r8.accessrelaxation.privateinstance.Sub1;
import com.android.tools.r8.accessrelaxation.privateinstance.Sub2;
import com.android.tools.r8.accessrelaxation.privateinstance.TestMain;
import com.android.tools.r8.accessrelaxation.privatestatic.A;
import com.android.tools.r8.accessrelaxation.privatestatic.B;
import com.android.tools.r8.accessrelaxation.privatestatic.BB;
import com.android.tools.r8.accessrelaxation.privatestatic.C;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public final class NonConstructorRelaxationTest extends AccessRelaxationTestBase {

  private static final String STRING = "java.lang.String";

  private boolean enableUnusedArgumentRemoval;

  @Parameterized.Parameters(name = "{0}, argument removal: {1}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values());
  }

  public NonConstructorRelaxationTest(
      TestParameters parameters, boolean enableUnusedArgumentRemoval) {
    super(parameters);
    this.enableUnusedArgumentRemoval = enableUnusedArgumentRemoval;
  }

  @Test
  public void testStaticMethodRelaxation() throws Exception {
    String expectedOutput =
        StringUtils.lines(
            "A::baz()",
            "A::bar()",
            "A::bar(int)",
            "A::blah(int)",
            "B::blah(int)",
            "BB::blah(int)",
            "A::foo()A::baz()A::bar()A::bar(int)",
            "B::bar() >> java.lang.IllegalAccessError",
            "java.lang.IllegalAccessError",
            "A::foo()A::baz()A::bar()A::bar(int)",
            "B::blah(int)",
            "A::foo()A::baz()A::bar()A::bar(int)",
            "B::bar() >> java.lang.IllegalAccessError",
            "C::bar(int)java.lang.IllegalAccessErrorB::bar() >> "
                + "java.lang.IllegalAccessErrorB::bar() >> java.lang.IllegalAccessError",
            "B::foo()A::foo()A::baz()A::bar()A::bar(int)",
            "C::blah(int)");
    Class<?> mainClass = C.class;
    if (parameters.isCfRuntime()) {
      // Only run JVM reference on CF runtimes.
      testForJvm()
          .addTestClasspath()
          .run(parameters.getRuntime(), mainClass)
          .assertSuccessWithOutput(expectedOutput);
    }

    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramFiles(ToolHelper.getClassFilesForTestPackage(mainClass.getPackage()))
            .addUnusedArgumentAnnotations()
            .enableConstantArgumentAnnotations()
            .enableInliningAnnotations()
            .enableNoHorizontalClassMergingAnnotations()
            .enableMemberValuePropagationAnnotations()
            .enableUnusedArgumentAnnotations(!enableUnusedArgumentRemoval)
            .addKeepMainRule(mainClass)
            .noMinification()
            .addKeepRules(
                // Note: we use '-checkdiscard' to indirectly check that the access relaxation is
                // done which leads to inlining of all pB*** methods so they are removed. Without
                // access relaxation inlining is not performed and method are kept.
                "-checkdiscard class " + A.class.getCanonicalName() + "{",
                "  *** pBaz();",
                "  *** pBar();",
                "  *** pBar1();",
                "  *** pBlah1();",
                "}",
                "-checkdiscard class " + B.class.getCanonicalName() + "{",
                "  *** pBlah1();",
                "}",
                "-checkdiscard class " + BB.class.getCanonicalName() + "{",
                "  *** pBlah1();",
                "}")
            .allowAccessModification()
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), mainClass);

    assertEquals(expectedOutput, result.getStdOut());

    CodeInspector inspector = result.inspector();

    MethodSignature barMethodSignatureAfterArgumentRemoval =
        enableUnusedArgumentRemoval
            ? new MethodSignature("bar$1", STRING, ImmutableList.of())
            : new MethodSignature("bar", STRING, ImmutableList.of("int"));
    assertPublic(inspector, A.class, new MethodSignature("baz", STRING, ImmutableList.of()));
    assertPublic(inspector, A.class, new MethodSignature("bar", STRING, ImmutableList.of()));
    assertPublic(inspector, A.class, barMethodSignatureAfterArgumentRemoval);

    MethodSignature blahMethodSignatureAfterArgumentRemoval =
        new MethodSignature(
            "blah",
            STRING,
            enableUnusedArgumentRemoval ? ImmutableList.of() : ImmutableList.of("int"));
    assertPublic(inspector, A.class, blahMethodSignatureAfterArgumentRemoval);
    assertPublic(inspector, BB.class, blahMethodSignatureAfterArgumentRemoval);
  }

  @Test
  public void testInstanceMethodRelaxationWithVerticalClassMerging() throws Exception {
    testInstanceMethodRelaxation(true);
  }

  @Test
  public void testInstanceMethodRelaxationWithoutVerticalClassMerging() throws Exception {
    testInstanceMethodRelaxation(false);
  }

  private void testInstanceMethodRelaxation(boolean enableVerticalClassMerging) throws Exception {
    String expectedOutput =
        StringUtils.lines(
            "Base::foo()",
            "Base::foo1()",
            "Base::foo2()",
            "Base::foo3()",
            "Sub1::foo1()",
            "Itf1::foo1(0) >> Sub1::foo1()",
            "Sub1::bar1(0)",
            "Sub1::foo3()",
            "Sub2::foo2()",
            "Itf2::foo2(0) >> Sub2::foo2()",
            "Sub2::bar2(0)",
            "Sub2::foo3()");
    Class<?> mainClass = TestMain.class;
    if (parameters.isCfRuntime()) {
      // Only run JVM reference on CF runtimes.
      testForJvm()
          .addTestClasspath()
          .run(parameters.getRuntime(), mainClass)
          .assertSuccessWithOutput(expectedOutput);
    }

    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramFiles(ToolHelper.getClassFilesForTestPackage(mainClass.getPackage()))
            .addKeepMainRule(mainClass)
            .addOptionsModification(o -> o.enableVerticalClassMerging = enableVerticalClassMerging)
            .enableConstantArgumentAnnotations()
            .enableNeverClassInliningAnnotations()
            .enableInliningAnnotations()
            .enableMemberValuePropagationAnnotations()
            .enableNoHorizontalClassMergingAnnotations()
            .noMinification()
            .addKeepRules(
                "-checkdiscard class " + Base.class.getCanonicalName() + "{",
                "  *** p*();",
                "}",
                "-checkdiscard class " + Sub1.class.getCanonicalName() + "{",
                "  *** p*();",
                "}",
                "-checkdiscard class " + Sub2.class.getCanonicalName() + "{",
                "  *** p*();",
                "}")
            .allowAccessModification()
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), mainClass);

    assertEquals(
        expectedOutput,
        result
            .getStdOut()
            .replace("java.lang.IncompatibleClassChangeError", "java.lang.IllegalAccessError"));

    // When vertical class merging is enabled, Itf1 is merged into Sub1 and Itf2 is merged into
    // Sub2, and as a result of these merges, neither Sub1 nor Sub2 end up in the output because of
    // inlining.
    CodeInspector codeInspector = result.inspector();
    assertPublic(codeInspector, Base.class, new MethodSignature("foo", STRING, ImmutableList.of()));

    // Base#foo?() can't be publicized due to Itf<1>#foo<1>().
    assertNotPublic(
        codeInspector, Base.class, new MethodSignature("foo1", STRING, ImmutableList.of()));
    assertNotPublic(
        codeInspector, Base.class, new MethodSignature("foo2", STRING, ImmutableList.of()));

    if (!enableVerticalClassMerging) {
      // Sub?#bar1(int) can be publicized as they don't bother each other.
      assertPublic(
          codeInspector, Sub1.class, new MethodSignature("bar1", STRING, ImmutableList.of("int")));
      assertPublic(
          codeInspector, Sub2.class, new MethodSignature("bar1", STRING, ImmutableList.of("int")));

      // Sub2#bar2(int) is unique throughout the hierarchy, hence publicized.
      assertPublic(
          codeInspector, Sub2.class, new MethodSignature("bar2", STRING, ImmutableList.of("int")));
    }
  }
}
