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

import static com.android.tools.r8.shaking.ProguardConfigurationParser.REPACKAGE_CLASSES;

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.DescriptorUtils;
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 RepackageParameterSyntheticOutlineTest extends RepackageTestBase {

  private final String NEW_DESCRIPTOR = "Lfoo/ClassWithCodeToBeOutlined;";
  private final String[] EXPECTED =
      new String[] {"Param::testParam", "Return::print", "Param::testParam", "Return::print"};

  @Parameters(name = "{1}, kind: {0}")
  public static List<Object[]> data() {
    return buildParameters(
        ImmutableList.of(REPACKAGE_CLASSES), // Repackage will use foo as the package name.
        getTestParameters().withDexRuntimes().withAllApiLevels().build());
  }

  public RepackageParameterSyntheticOutlineTest(
      String flattenPackageHierarchyOrRepackageClasses, TestParameters parameters) {
    super(flattenPackageHierarchyOrRepackageClasses, parameters);
  }

  @Test
  public void testRuntime() throws Exception {
    testForRuntime(parameters)
        .addProgramClasses(Param.class, Return.class)
        .addProgramClassFileData(
            rewrittenPackageForClassWithCodeToBeOutlined(),
            rewrittenMainWithMethodReferencesToCodeToBeOutlined())
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines(EXPECTED);
  }

  @Test
  public void testR8() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClasses(Param.class, Return.class)
        .addProgramClassFileData(
            rewrittenPackageForClassWithCodeToBeOutlined(),
            rewrittenMainWithMethodReferencesToCodeToBeOutlined())
        .addKeepMainRule(Main.class)
        .addKeepClassRulesWithAllowObfuscation(Param.class, Return.class)
        .setMinApi(parameters.getApiLevel())
        .enableInliningAnnotations()
        .addOptionsModification(
            options -> {
              options.outline.minSize = 2;
              options.outline.threshold = 2;
            })
        .apply(this::configureRepackaging)
        .addKeepPackageNamesRule("bar**")
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines(EXPECTED);
  }

  private byte[] rewrittenPackageForClassWithCodeToBeOutlined() throws Exception {
    return transformer(ClassWithCodeToBeOutlined.class)
        .setClassDescriptor(NEW_DESCRIPTOR)
        .transform();
  }

  private byte[] rewrittenMainWithMethodReferencesToCodeToBeOutlined() throws Exception {
    return transformer(Main.class)
        .replaceClassDescriptorInMethodInstructions(
            DescriptorUtils.javaTypeToDescriptor(ClassWithCodeToBeOutlined.class.getTypeName()),
            NEW_DESCRIPTOR)
        .transform();
  }

  // Will be renamed by repackaging
  public static class Param {

    @NeverInline
    public void testParam() {
      System.out.println("Param::testParam");
    }

    @NeverInline
    public Return getReturn() {
      return new Return();
    }
  }

  // Will be renamed by repackaging
  public static class Return {

    public void print() {
      System.out.println("Return::print");
    }
  }

  // Renamed to baz.ClassWithCodeToBeOutlined such that we can keep this package name.
  public static class ClassWithCodeToBeOutlined {

    @NeverInline
    public static Return foo(Param param) {
      param.testParam();
      return param.getReturn();
    }

    @NeverInline
    public static Return bar(Param param) {
      param.testParam();
      return param.getReturn();
    }
  }

  public static class Main {

    public static void main(String[] args) {
      Param param = new Param();
      ClassWithCodeToBeOutlined.foo(param).print();
      ClassWithCodeToBeOutlined.bar(param).print();
    }
  }
}
