// Copyright (c) 2019, 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.ir.optimize.classinliner;

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.Assert.assertEquals;

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class ClassInlinerSimplePairBuilderTest extends ClassInlinerTestBase {

  private static final String EXPECTED =
      StringUtils.lines(
          "[before] first = null",
          "[after] first = f1",
          "Pair(f1, <null>)",
          "[before] second = null",
          "[after] second = s2",
          "Pair(<null>, s2)",
          "[before] first = null",
          "[after] first = f3",
          "[before] second = null",
          "[after] second = s4",
          "Pair(f3, s4)");

  private final TestParameters parameters;

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

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

  @Test
  public void testR8() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(ClassInlinerSimplePairBuilderTest.class)
        .addKeepMainRule(TestClass.class)
        // TODO(b/143129517): This relies on PairBuilder::build being inlined, thus the limit of 6.
        .addOptionsModification(options -> options.inliningInstructionLimit = 6)
        .enableInliningAnnotations()
        .noMinification()
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(this::inspect)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
  }

  @Test
  public void testExpectedBehavior() throws Exception {
    testForRuntime(parameters)
        .addInnerClasses(ClassInlinerSimplePairBuilderTest.class)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
  }

  private void inspect(CodeInspector inspector) {
    ClassSubject clazz = inspector.clazz(TestClass.class);
    if (parameters.isCfRuntime()) {
      assertThat(inspector.clazz(PairBuilder.class), isPresent());

      // const-string canonicalization is disabled in CF, which helps ClassInliner identify
      // PairBuilder as candidate.
      Set<String> expected =
          ImmutableSet.of(StringBuilder.class.getTypeName(), PairBuilder.class.getTypeName());
      assertEquals(expected, collectTypes(clazz.uniqueMethodWithName("testSimpleBuilder1")));
      assertEquals(expected, collectTypes(clazz.uniqueMethodWithName("testSimpleBuilder2")));
      assertEquals(expected, collectTypes(clazz.uniqueMethodWithName("testSimpleBuilder3")));
    } else {
      assertThat(inspector.clazz(PairBuilder.class), not(isPresent()));

      Set<String> expected = ImmutableSet.of(StringBuilder.class.getTypeName());
      assertEquals(expected, collectTypes(clazz.uniqueMethodWithName("testSimpleBuilder1")));
      assertEquals(expected, collectTypes(clazz.uniqueMethodWithName("testSimpleBuilder2")));
      assertEquals(expected, collectTypes(clazz.uniqueMethodWithName("testSimpleBuilder3")));
    }
  }

  static class TestClass {

    public static void main(String[] args) {
      testSimpleBuilder1();
      testSimpleBuilder2();
      testSimpleBuilder3();
    }

    @NeverInline
    static void testSimpleBuilder1() {
      System.out.println(new PairBuilder<String, String>().setFirst("f1").build().myToString());
    }

    @NeverInline
    static void testSimpleBuilder2() {
      System.out.println(new PairBuilder<String, String>().setSecond("s2").build().myToString());
    }

    @NeverInline
    static void testSimpleBuilder3() {
      System.out.println(
          new PairBuilder<String, String>().setFirst("f3").setSecond("s4").build().myToString());
    }
  }

  static class Pair<F, S> {
    final F first;
    final S second;

    Pair(F first, S second) {
      this.first = first;
      this.second = second;
    }

    String myToString() {
      return "Pair("
          + (first == null ? "<null>" : first)
          + ", "
          + (second == null ? "<null>" : second)
          + ")";
    }
  }

  static class PairBuilder<F, S> {

    F first;
    S second = null;

    PairBuilder<F, S> setFirst(F first) {
      System.out.println("[before] first = " + this.first);
      this.first = first;
      System.out.println("[after] first = " + this.first);
      return this;
    }

    PairBuilder<F, S> setSecond(S second) {
      System.out.println("[before] second = " + this.second);
      this.second = second;
      System.out.println("[after] second = " + this.second);
      return this;
    }

    public Pair<F, S> build() {
      return new Pair<>(first, second);
    }
  }
}
