// Copyright (c) 2022, 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.classmerging.horizontal;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

/** Reproduction of b/231900726. */
@RunWith(Parameterized.class)
public class VirtualMethodMergingWithAbsentMethodAndSuperClassMergingTest extends TestBase {

  @Parameter(0)
  public ClassWrapper upperMergeTarget;

  @Parameter(1)
  public ClassWrapper lowerMergeTarget;

  @Parameter(2)
  public TestParameters parameters;

  @Parameters(name = "{2}, upper merge target: {0}, lower merge target: {1}")
  public static List<Object[]> data() {
    return buildParameters(
        ImmutableList.of(ClassWrapper.create(A.class), ClassWrapper.create(B.class)),
        ImmutableList.of(ClassWrapper.create(C.class), ClassWrapper.create(D.class)),
        getTestParameters().withAllRuntimesAndApiLevels().build());
  }

  // Use a ClassWrapper to wrap the classes such that the string representation of the test do not
  // exceed to many characters.
  public static class ClassWrapper {
    public final Class<?> clazz;

    private ClassWrapper(Class<?> clazz) {
      this.clazz = clazz;
    }

    public static ClassWrapper create(Class<?> clazz) {
      return new ClassWrapper(clazz);
    }

    public String getTypeName() {
      return clazz.getTypeName();
    }

    public boolean is(Class<?> clazz) {
      return this.clazz == clazz;
    }

    @Override
    public String toString() {
      return clazz.getSimpleName();
    }
  }

  @Test
  public void test() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(getClass())
        .addKeepMainRule(Main.class)
        // Control the targets of the horizontal class merger.
        .addOptionsModification(
            options ->
                options.testing.horizontalClassMergingTarget =
                    (appView, candidates, target) -> {
                      if (Iterables.any(
                          candidates,
                          candidate -> candidate.getTypeName().equals(A.class.getTypeName()))) {
                        return Iterables.find(
                            candidates,
                            candidate ->
                                candidate.getTypeName().equals(upperMergeTarget.getTypeName()));
                      }
                      if (Iterables.any(
                          candidates,
                          candidate -> candidate.getTypeName().equals(C.class.getTypeName()))) {
                        return Iterables.find(
                            candidates,
                            candidate ->
                                candidate.getTypeName().equals(lowerMergeTarget.getTypeName()));
                      }
                      return target;
                    })
        // Verify that the targets are as expected.
        .addHorizontallyMergedClassesInspector(
            inspector ->
                inspector
                    .applyIf(
                        upperMergeTarget.is(A.class),
                        i -> i.assertMergedInto(B.class, A.class),
                        i -> i.assertMergedInto(A.class, B.class))
                    .applyIf(
                        lowerMergeTarget.is(C.class),
                        i -> i.assertMergedInto(D.class, C.class),
                        i -> i.assertMergedInto(C.class, D.class))
                    .assertNoOtherClassesMerged())
        .setMinApi(parameters.getApiLevel())
        .compile()
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines("A", "B", "C", "A");
  }

  static class Main {

    public static void main(String[] args) {
      new A().m();
      new B().m();
      new C().m();
      new D().m();
    }
  }

  static class A {

    void m() {
      System.out.println("A");
    }
  }

  static class B {

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

  static class C extends A {

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

  static class D extends A {}
}
