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

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NeverPropagateValue;
import com.android.tools.r8.NoHorizontalClassMerging;
import com.android.tools.r8.NoVerticalClassMerging;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.BooleanUtils;
import com.google.common.collect.ImmutableList;
import java.util.List;
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 CallSiteOptimizationPinnedMethodOverridePropagationTest extends TestBase {

  private static final String CLASS_PREFIX =
      "com.android.tools.r8.ir.optimize.callsites.CallSiteOptimizationPinnedMethodOverridePropagationTest$";

  private final boolean enableExperimentalArgumentPropagation;
  private final TestParameters parameters;

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

  public CallSiteOptimizationPinnedMethodOverridePropagationTest(
      boolean enableExperimentalArgumentPropagation, TestParameters parameters) {
    this.enableExperimentalArgumentPropagation = enableExperimentalArgumentPropagation;
    this.parameters = parameters;
  }

  @Test
  public void test() throws Exception {
    R8TestCompileResult compiled =
        testForR8(parameters.getBackend())
            .addProgramClasses(
                Arg.class, Arg1.class, Arg2.class, Call.class, CallImpl.class, Main2.class)
            .addKeepRules(
                ImmutableList.of(
                    "-keep interface " + CLASS_PREFIX + "Arg",
                    "-keep interface "
                        + CLASS_PREFIX
                        + "Call { \npublic void print("
                        + CLASS_PREFIX
                        + "Arg); \n}",
                    "-keep class "
                        + CLASS_PREFIX
                        + "Main2 { \npublic static void main(java.lang.String[]); \npublic static "
                        + CLASS_PREFIX
                        + "Arg getArg1(); \npublic static "
                        + CLASS_PREFIX
                        + "Arg getArg2(); \npublic static "
                        + CLASS_PREFIX
                        + "Call getCaller(); \n}"))
            .addOptionsModification(
                options ->
                    options
                        .callSiteOptimizationOptions()
                        .setEnableExperimentalArgumentPropagation(
                            enableExperimentalArgumentPropagation))
            .enableNoVerticalClassMergingAnnotations()
            .enableNoHorizontalClassMergingAnnotations()
            .enableInliningAnnotations()
            .enableMemberValuePropagationAnnotations()
            .setMinApi(parameters.getApiLevel())
            .compile();
    compiled.run(parameters.getRuntime(), Main2.class).assertSuccessWithOutputLines("Arg1");
    testForD8()
        .addProgramClasses(Main.class)
        .setMinApi(parameters.getApiLevel())
        .compile()
        .addRunClasspathFiles(compiled.writeToZip())
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines("Arg1", "Arg2");
  }

  // Kept
  @NoVerticalClassMerging
  interface Arg {

    @NeverInline
    @NeverPropagateValue
    String getString();
  }

  @NoVerticalClassMerging
  @NoHorizontalClassMerging
  static class Arg1 implements Arg {

    @Override
    @NeverInline
    @NeverPropagateValue
    public String getString() {
      return "Arg1";
    }
  }

  @NoVerticalClassMerging
  @NoHorizontalClassMerging
  static class Arg2 implements Arg {

    @Override
    @NeverInline
    @NeverPropagateValue
    public String getString() {
      return "Arg2";
    }
  }

  @NoVerticalClassMerging
  interface Call {

    // Kept.
    @NeverInline
    @NeverPropagateValue
    void print(Arg arg);
  }

  @NoVerticalClassMerging
  static class CallImpl implements Call {

    @Override
    @NeverInline
    @NeverPropagateValue
    public void print(Arg arg) {
      System.out.println(arg.getString());
    }
  }

  @NoVerticalClassMerging
  static class Main2 {

    // Kept.
    public static void main(String[] args) {
      // This would propagate Arg1 to print while it should not.
      getCaller().print(new Arg1());
    }

    // Kept.
    public static Arg getArg1() {
      return new Arg1();
    }

    // Kept.
    public static Arg getArg2() {
      return new Arg2();
    }

    // Kept.
    public static Call getCaller() {
      return new CallSiteOptimizationPinnedMethodOverridePropagationTest.CallImpl();
    }
  }

  static class Main {

    public static void main(String[] args) {
      Arg arg1 = Main2.getArg1();
      Arg arg2 = Main2.getArg2();
      Call caller = Main2.getCaller();
      caller.print(arg1);
      caller.print(arg2);
    }
  }
}
