// 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.classmerging.horizontal;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import org.junit.Test;

public class PinnedClassMemberReferenceTest extends HorizontalClassMergingTestBase {
  public PinnedClassMemberReferenceTest(
      TestParameters parameters, boolean enableHorizontalClassMerging) {
    super(parameters, enableHorizontalClassMerging);
  }

  private R8FullTestBuilder testCommon() throws Exception {
    return testForR8(parameters.getBackend())
        .addInnerClasses(getClass())
        .addKeepMainRule(Main.class)
        .addOptionsModification(
            options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
        .noMinification()
        .enableInliningAnnotations()
        .enableNeverClassInliningAnnotations()
        .setMinApi(parameters.getApiLevel());
  }

  private R8TestRunResult runAndAssertOutput(R8FullTestBuilder builder) throws Exception {
    return builder
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines(
            "a", "b", "foo a: bar", "foo b: baz", "fields a: bar", "fields b: baz");
  }

  @Test
  public void testWithoutKeepRules() throws Exception {
    // This is just a small check ensure that without the keep rules the classes are merged.
    assumeTrue(enableHorizontalClassMerging);
    assumeTrue(parameters.isCfRuntime());

    runAndAssertOutput(testCommon())
        .inspect(
            codeInspector -> {
              ClassSubject aClassSubject = codeInspector.clazz(A.class);
              assertThat(aClassSubject, isPresent());

              assertThat(codeInspector.clazz(B.class), not(isPresent()));

              ClassSubject cClassSubject = codeInspector.clazz(C.class);
              assertThat(cClassSubject, isPresent());
              assertThat(cClassSubject.field(aClassSubject.getFinalName(), "a"), isPresent());
              assertThat(cClassSubject.field(aClassSubject.getFinalName(), "b"), isPresent());

              assertThat(
                  cClassSubject.method("void", "foo", aClassSubject.getFinalName()), isPresent());
            });
  }

  @Test
  public void testWithKeepRules() throws Exception {
    runAndAssertOutput(
            testCommon()
                .addKeepRules(
                    "-keepclassmembers class " + C.class.getTypeName() + " { ",
                    "  " + A.class.getTypeName() + " a;",
                    "  " + C.class.getTypeName() + " c;",
                    "  void foo(" + A.class.getTypeName() + ");",
                    "  void foo(" + B.class.getTypeName() + ");",
                    "}"))
        .inspect(
            codeInspector -> {
              ClassSubject aClassSubject = codeInspector.clazz(A.class);
              assertThat(aClassSubject, isPresent());

              ClassSubject bClassSubject = codeInspector.clazz(B.class);
              assertThat(bClassSubject, isPresent());

              ClassSubject cClassSubject = codeInspector.clazz(C.class);
              assertThat(cClassSubject, isPresent());
              assertThat(cClassSubject.field(aClassSubject.getFinalName(), "a"), isPresent());
              assertThat(cClassSubject.field(bClassSubject.getFinalName(), "b"), isPresent());

              assertThat(
                  cClassSubject.method("void", "foo", aClassSubject.getFinalName()), isPresent());
              assertThat(
                  cClassSubject.method("void", "foo", bClassSubject.getFinalName()), isPresent());
            });
  }

  @NeverClassInline
  public static class A {
    public A() {
      System.out.println("a");
    }

    @NeverInline
    public String bar() {
      return "bar";
    }
  }

  @NeverClassInline
  public static class B {
    public B() {
      System.out.println("b");
    }

    @NeverInline
    public String baz() {
      return "baz";
    }
  }

  @NeverClassInline
  public static class C {
    A a;
    B b;

    public C(A a, B b) {
      this.a = a;
      this.b = b;
    }

    @NeverInline
    public void foo(A a2) {
      System.out.println("foo a: " + a2.bar());
    }

    @NeverInline
    public void foo(B b) {
      System.out.println("foo b: " + b.baz());
    }

    @NeverInline
    public void fields() {
      System.out.println("fields a: " + a.bar());
      System.out.println("fields b: " + b.baz());
    }
  }

  public static class Main {
    public static void main(String[] args) {
      A a = new A();
      B b = new B();
      C c = new C(a, b);
      c.foo(a);
      c.foo(b);
      c.fields();
    }
  }
}
