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

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.horizontalclassmerging.ConditionalMethodRulesAndHorizontalMergingTest.Example1.BaseClass;
import com.android.tools.r8.horizontalclassmerging.ConditionalMethodRulesAndHorizontalMergingTest.Example1.MyHiddenMethodCaller;
import com.android.tools.r8.horizontalclassmerging.ConditionalMethodRulesAndHorizontalMergingTest.Example2.MyFieldValuePrinter;
import com.android.tools.r8.horizontalclassmerging.ConditionalMethodRulesAndHorizontalMergingTest.Example2.PrintableFieldInterface;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.lang.reflect.Field;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  static final String EXPECTED =
      StringUtils.lines("on Base", "on Sub", "intField = 42", "stringField = Hello!");

  private final TestParameters parameters;

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withDefaultRuntimes().withApiLevel(AndroidApiLevel.B).build();
  }

  public ConditionalMethodRulesAndHorizontalMergingTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  @Test
  public void testReference() throws Exception {
    testForRuntime(parameters)
        .addProgramClasses(TestClass.class)
        .addProgramClassesAndInnerClasses(getExampleClasses())
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
  }

  @Test
  public void testR8() throws Exception {
    testForR8(parameters.getBackend())
        .addKeepMainRule(TestClass.class)
        // The following rules are what was generated by the keepanno extraction for the doc tests.
        .addKeepRules(
            "-if class " + typeName(MyHiddenMethodCaller.class) + " {",
            "  void callHiddenMethod(" + typeName(BaseClass.class) + ");",
            "}",
            "-keepclassmembers class * extends " + typeName(BaseClass.class) + " {",
            "  *** hiddenMethod();",
            "}",
            "-if class " + typeName(MyHiddenMethodCaller.class) + " {",
            "  void callHiddenMethod(" + typeName(BaseClass.class) + ");",
            "}",
            "-keepclassmembers class " + typeName(BaseClass.class) + " {",
            "  *** hiddenMethod();",
            "}",
            "-if class " + typeName(MyFieldValuePrinter.class) + " {",
            "  void printFieldValues(" + typeName(PrintableFieldInterface.class) + ");",
            "}",
            "-keepclassmembers class * extends " + typeName(PrintableFieldInterface.class) + " {",
            "  *** *;",
            "}"
            // Removed the rule variant on the base interface as it does not have fields.
            )
        .addProgramClasses(TestClass.class)
        .addProgramClassesAndInnerClasses(getExampleClasses())
        .setMinApi(parameters)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
  }

  public List<Class<?>> getExampleClasses() {
    return ImmutableList.of(Example1.class, Example2.class);
  }

  static class TestClass {
    public static void main(String[] args) throws Exception {
      Example1.run();
      Example2.run();
    }
  }

  static class Example1 {

    static class BaseClass {
      void hiddenMethod() {
        System.out.println("on Base");
      }
    }

    static class SubClass extends BaseClass {
      void hiddenMethod() {
        System.out.println("on Sub");
      }
    }

    public static class MyHiddenMethodCaller {
      public void callHiddenMethod(BaseClass base) throws Exception {
        base.getClass().getDeclaredMethod("hiddenMethod").invoke(base);
      }
    }

    static void run() throws Exception {
      new MyHiddenMethodCaller().callHiddenMethod(new BaseClass());
      new MyHiddenMethodCaller().callHiddenMethod(new SubClass());
    }
  }

  static class Example2 {

    interface PrintableFieldInterface {}

    static class ClassWithFields implements PrintableFieldInterface {
      final int intField = 42;
      String stringField = "Hello!";
    }

    public static class MyFieldValuePrinter {
      public void printFieldValues(PrintableFieldInterface objectWithFields) throws Exception {
        for (Field field : objectWithFields.getClass().getDeclaredFields()) {
          System.out.println(field.getName() + " = " + field.get(objectWithFields));
        }
      }
    }

    static void run() throws Exception {
      new MyFieldValuePrinter().printFieldValues(new ClassWithFields());
    }
  }
}
