// 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.profile.art;

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

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.profile.art.model.ExternalArtProfile;
import com.android.tools.r8.profile.art.model.ExternalArtProfileClassRule;
import com.android.tools.r8.profile.art.model.ExternalArtProfileMethodRule;
import com.android.tools.r8.profile.art.utils.ArtProfileTestingUtils;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.MethodReferenceUtils;
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 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;

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

  private static final ClassReference mainClassReference = Reference.classFromClass(Main.class);
  private static final MethodReference mainMethodReference =
      MethodReferenceUtils.mainMethod(Main.class);

  private static final ClassReference fooClassReference = Reference.classFromClass(Foo.class);
  private static final MethodReference helloMethodReference =
      MethodReferenceUtils.methodFromMethod(Foo.class, "hello");

  private static final ClassReference barClassReference = Reference.classFromClass(Bar.class);
  private static final MethodReference worldMethodReference =
      MethodReferenceUtils.methodFromMethod(Bar.class, "world");

  @Parameter(0)
  public TestParameters parameters;

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withNoneRuntime().build();
  }

  @Test
  public void test() throws Exception {
    Box<ExternalArtProfile> residualArtProfile = new Box<>();
    testForR8(Backend.DEX)
        .addInnerClasses(getClass())
        .addKeepMainRule(Main.class)
        .addHorizontallyMergedClassesInspector(
            inspector ->
                inspector.assertMergedInto(Foo.class, Bar.class).assertNoOtherClassesMerged())
        .apply(
            testBuilder ->
                ArtProfileTestingUtils.addArtProfileForRewriting(
                    getArtProfile(), residualArtProfile::set, testBuilder))
        .enableInliningAnnotations()
        .setMinApi(AndroidApiLevel.LATEST)
        .compile()
        .inspect(inspector -> inspect(inspector, residualArtProfile.get()));
  }

  public ExternalArtProfile getArtProfile() {
    return ExternalArtProfile.builder()
        .addRules(
            ExternalArtProfileClassRule.builder().setClassReference(mainClassReference).build(),
            ExternalArtProfileMethodRule.builder().setMethodReference(mainMethodReference).build(),
            ExternalArtProfileClassRule.builder().setClassReference(fooClassReference).build(),
            ExternalArtProfileMethodRule.builder().setMethodReference(helloMethodReference).build(),
            ExternalArtProfileClassRule.builder().setClassReference(barClassReference).build(),
            ExternalArtProfileMethodRule.builder().setMethodReference(worldMethodReference).build())
        .build();
  }

  public ExternalArtProfile getExpectedResidualArtProfile(CodeInspector inspector) {
    ClassSubject barClassSubject = inspector.clazz(Bar.class);
    assertThat(barClassSubject, isPresentAndRenamed());

    MethodSubject helloMethodSubject = barClassSubject.uniqueMethodWithOriginalName("hello");
    assertThat(helloMethodSubject, isPresentAndRenamed());

    MethodSubject worldMethodSubject = barClassSubject.uniqueMethodWithOriginalName("world");
    assertThat(worldMethodSubject, isPresentAndRenamed());

    return ExternalArtProfile.builder()
        .addRules(
            ExternalArtProfileClassRule.builder().setClassReference(mainClassReference).build(),
            ExternalArtProfileMethodRule.builder().setMethodReference(mainMethodReference).build(),
            ExternalArtProfileClassRule.builder()
                .setClassReference(barClassSubject.getFinalReference())
                .build(),
            ExternalArtProfileMethodRule.builder()
                .setMethodReference(helloMethodSubject.getFinalReference())
                .build(),
            ExternalArtProfileMethodRule.builder()
                .setMethodReference(worldMethodSubject.getFinalReference())
                .build())
        .build();
  }

  private void inspect(CodeInspector inspector, ExternalArtProfile residualArtProfile) {
    assertEquals(getExpectedResidualArtProfile(inspector), residualArtProfile);
  }

  static class Main {

    public static void main(String[] args) {
      Foo.hello();
      Bar.world();
    }
  }

  static class Foo {

    @NeverInline
    static void hello() {
      System.out.print("Hello");
    }
  }

  static class Bar {

    @NeverInline
    static void world() {
      System.out.println(", world!");
    }
  }
}
