// 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.ir.optimize.inliner;

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

import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
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 class MultipleIndirectCallSitesTest extends TestBase {

  private final boolean invokeMethodOnA;
  private final TestParameters parameters;

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

  public MultipleIndirectCallSitesTest(boolean invokeMethodOnA, TestParameters parameters) {
    this.invokeMethodOnA = invokeMethodOnA;
    this.parameters = parameters;
  }

  @Test
  public void test() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(MultipleIndirectCallSitesTest.class)
        .addKeepMainRule(TestClass.class)
        .addKeepClassRulesWithAllowObfuscation(B.class)
        // Keep invokeMethodOnA() if specified by the test configuration. If invokeMethodOnA() is
        // kept, there is a single call site that invokes A.m(). However, this does not mean that
        // A.m() has a single call site, so it should not allow inlining of A.m().
        .addKeepRules(getKeepRules())
        .setMinApi(parameters.getRuntime())
        .compile()
        .inspect(this::verifyInlining)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("A.m()", "A.m()", "A.m()", "A.m()", "A.m()");
  }

  private List<String> getKeepRules() {
    if (invokeMethodOnA) {
      return ImmutableList.of(
          "-keep class " + TestClass.class.getName() + " { void invokeMethodOnA(); }");
    }
    return ImmutableList.of();
  }

  private void verifyInlining(CodeInspector inspector) {
    ClassSubject testClassSubject = inspector.clazz(TestClass.class);
    assertThat(testClassSubject.mainMethod(), isPresent());

    ClassSubject aClassSubject = inspector.clazz(A.class);
    assertThat(aClassSubject, isPresent());

    MethodSubject methodSubject = aClassSubject.uniqueMethodWithName("m");
    assertThat(methodSubject, isPresent());
    assertEquals(
        5,
        testClassSubject
            .mainMethod()
            .streamInstructions()
            .filter(
                instruction ->
                    instruction.isInvokeVirtual()
                        && instruction
                            .getMethod()
                            .name
                            .toSourceString()
                            .equals(methodSubject.getFinalName()))
            .count());
  }

  static class TestClass {

    public static void main(String[] args) {
      I instance = new A();
      instance.m();
      instance.m();
      instance.m();
      instance.m();
      instance.m();
    }

    static void invokeMethodOnA() {
      new A().m();
    }
  }

  interface I {

    void m();
  }

  @NeverClassInline
  static class A implements I {

    @Override
    public void m() {
      System.out.print("A");
      System.out.print(".");
      System.out.print("m");
      System.out.print("(");
      System.out.println(")");
    }
  }

  static class B implements I {

    @Override
    public void m() {
      System.out.println("B.m()");
    }
  }
}
