// 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.string;

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 static org.junit.Assume.assumeTrue;

import com.android.tools.r8.D8TestRunResult;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRunResult;
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.android.tools.r8.utils.codeinspector.InstructionSubject.JumboStringMode;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class StringConcatenationTest extends TestBase {
  private static final Class<?> MAIN = StringConcatenationTestClass.class;
  private static final String JAVA_OUTPUT = StringUtils.lines(
      // trivialSequence
      "xyz",
      // builderWithInitialValue
      "Hello,R8",
      // builderWithCapacity
      "42",
      // nonStringArgs
      "42",
      // typeConversion
      "0.14 0 false null",
      // typeConversion_withPhis
      "3.14 3 0",
      // nestedBuilders_appendBuilderItself
      "Hello,R8",
      // nestedBuilders_appendBuilderResult
      "Hello,R8",
      // nestedBuilders_conditional
      "Hello,R8",
      // concatenatedBuilders_init
      "Hello,R8",
      // concatenatedBuilders_append
      "Hello,R8",
      // concatenatedBuilders_conditional
      "Hello,R8",
      // simplePhi
      "Hello,",
      "Hello,D8",
      // phiAtInit
      "Hello,R8",
      // phiWithDifferentInits
      "Hello,R8",
      // conditionalPhiWithoutAppend
      "initial:suffix",
      // loop
      "na;na;na;na;na;na;na;na;Batman!",
      // loopWithBuilder
      "na;na;na;na;na;na;na;na;Batman!"
  );

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

  private final TestParameters parameters;

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

  @Test
  public void testJVMOutput() throws Exception {
    assumeTrue("Only run JVM reference on CF runtimes", parameters.isCfRuntime());
    testForJvm()
        .addTestClasspath()
        .run(parameters.getRuntime(), MAIN)
        .assertSuccessWithOutput(JAVA_OUTPUT);
  }

  private void test(TestRunResult result, boolean isR8, boolean isReleaseMode) throws Exception {
    // TODO(b/154899065): The lack of subtyping made the escape analysis to regard
    //    StringBuilder#toString as an alias-introducing instruction.
    //    For now, debug v.s. release mode of D8 have the same result.
    //    Use library modeling to allow this optimization.

    // Smaller is better in general. If the counter part is zero, that means non-string arguments
    // are used, and in that case bigger is better.
    // If the fixed count is used, that means StringBuilderOptimization should keep things as-is
    // or there would be no observable differences (# of builders could be different).
    int expectedCount;

    CodeInspector codeInspector = result.inspector();
    ClassSubject mainClass = codeInspector.clazz(MAIN);

    MethodSubject method = mainClass.uniqueMethodWithName("unusedBuilder");
    if (isR8) {
      assertThat(method, not(isPresent()));
    } else {
      assertThat(method, isPresent());
      assertEquals(0, countConstString(method));
    }

    method = mainClass.uniqueMethodWithName("trivialSequence");
    assertThat(method, isPresent());
    expectedCount = isR8 ? 1 : 3;
    assertEquals(expectedCount, countConstString(method));

    method = mainClass.uniqueMethodWithName("builderWithInitialValue");
    assertThat(method, isPresent());
    expectedCount = isR8 ? 1 : 3;
    assertEquals(expectedCount, countConstString(method));

    method = mainClass.uniqueMethodWithName("builderWithCapacity");
    assertThat(method, isPresent());
    expectedCount = isR8 ? 1 : 0;
    assertEquals(expectedCount, countConstString(method));

    method = mainClass.uniqueMethodWithName("nonStringArgs");
    assertThat(method, isPresent());
    expectedCount = isR8 ? 1 : 0;
    assertEquals(expectedCount, countConstString(method));

    method = mainClass.uniqueMethodWithName("typeConversion");
    assertThat(method, isPresent());
    expectedCount = isR8 ? 1 : 0;
    assertEquals(expectedCount, countConstString(method));

    method = mainClass.uniqueMethodWithName("typeConversion_withPhis");
    assertThat(method, isPresent());
    assertEquals(0, countConstString(method));

    method = mainClass.uniqueMethodWithName("nestedBuilders_appendBuilderItself");
    assertThat(method, isPresent());
    // TODO(b/113859361): merge builders
    expectedCount = 3;
    assertEquals(expectedCount, countConstString(method));

    method = mainClass.uniqueMethodWithName("nestedBuilders_appendBuilderResult");
    assertThat(method, isPresent());
    // TODO(b/113859361): merge builders
    expectedCount = 3;
    assertEquals(expectedCount, countConstString(method));

    method = mainClass.uniqueMethodWithName("nestedBuilders_conditional");
    assertThat(method, isPresent());
    assertEquals(4, countConstString(method));

    method = mainClass.uniqueMethodWithName("concatenatedBuilders_init");
    assertThat(method, isPresent());
    // TODO(b/113859361): merge builders
    expectedCount = 2;
    assertEquals(expectedCount, countConstString(method));

    method = mainClass.uniqueMethodWithName("concatenatedBuilders_append");
    assertThat(method, isPresent());
    // TODO(b/113859361): merge builders
    expectedCount = 2;
    assertEquals(expectedCount, countConstString(method));

    method = mainClass.uniqueMethodWithName("concatenatedBuilders_conditional");
    assertThat(method, isPresent());
    // TODO(b/113859361): merge builders
    expectedCount = 4;
    assertEquals(expectedCount, countConstString(method));

    method = mainClass.uniqueMethodWithName("simplePhi");
    assertThat(method, isPresent());
    assertEquals(4, countConstString(method));

    method = mainClass.uniqueMethodWithName("phiAtInit");
    assertThat(method, isPresent());
    assertEquals(3, countConstString(method));

    method = mainClass.uniqueMethodWithName("phiWithDifferentInits");
    assertThat(method, isPresent());
    assertEquals(3, countConstString(method));

    method = mainClass.uniqueMethodWithName("conditionalPhiWithoutAppend");
    assertThat(method, isPresent());
    assertEquals(3, countConstString(method));

    method = mainClass.uniqueMethodWithName("loop");
    assertThat(method, isPresent());
    assertEquals(3, countConstString(method));

    method = mainClass.uniqueMethodWithName("loopWithBuilder");
    assertThat(method, isPresent());
    assertEquals(2, countConstString(method));
  }

  private long countConstString(MethodSubject method) {
    return method.streamInstructions().filter(i -> i.isConstString(JumboStringMode.ALLOW)).count();
  }

  @Test
  public void testD8() throws Exception {
    assumeTrue("Only run D8 for Dex backend", parameters.isDexRuntime());

    D8TestRunResult result =
        testForD8()
            .debug()
            .addProgramClasses(MAIN)
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), MAIN)
            .assertSuccessWithOutput(JAVA_OUTPUT);
    test(result, false, false);

    result =
        testForD8()
            .release()
            .addProgramClasses(MAIN)
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), MAIN)
            .assertSuccessWithOutput(JAVA_OUTPUT);
    test(result, false, true);
  }

  @Test
  public void testR8() throws Exception {
    assumeTrue("CF does not rewrite move results.", parameters.isDexRuntime());

    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramClasses(MAIN)
            .enableInliningAnnotations()
            .addKeepMainRule(MAIN)
            .noMinification()
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), MAIN)
            .assertSuccessWithOutput(JAVA_OUTPUT);
    test(result, true, true);
  }
}
