// Copyright (c) 2016, 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.smali;

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

import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class JumboStringTest extends SmaliTestBase {
  private static Pair<StringBuilder, StringBuilder> builders;
  private final TestParameters parameters;

  @BeforeClass
  public static void createBuilders() {
    StringBuilder builder = new StringBuilder();
    StringBuilder expectedBuilder = new StringBuilder();
    builder.append("    new-instance         v0, Ljava/lang/StringBuilder;");
    builder.append("    invoke-direct        { v0 }, Ljava/lang/StringBuilder;-><init>()V");
    for (int i = 0; i <= 0xffff + 2; i++) {
      String prefixed = StringUtils.zeroPrefix(i, 5);
      expectedBuilder.append(prefixed);
      expectedBuilder.append(StringUtils.lines(""));
      builder.append("  const-string         v1, \"" + prefixed + "\\n\"");
      builder.append(
          "  invoke-virtual       { v0, v1 }, Ljava/lang/StringBuilder;"
              + "->append(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    }
    builder.append(
        "    invoke-virtual       { v0 }, Ljava/lang/StringBuilder;"
            + "->toString()Ljava/lang/String;");
    builder.append(StringUtils.lines("    move-result-object   v0"));
    builder.append(StringUtils.lines("    return-object        v0"));
    builders = new Pair<>(builder, expectedBuilder);
  }

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

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

  @Test
  public void test() throws Exception {
    SmaliBuilder smaliBuilder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    smaliBuilder.addStaticMethod(
        "java.lang.String",
        DEFAULT_METHOD_NAME,
        ImmutableList.of(),
        2,
        builders.getFirst().toString()
    );

    smaliBuilder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    invoke-static       {}, LTest;->method()Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void"
    );

    testForR8(parameters.getBackend())
        .addProgramDexFileData(smaliBuilder.compile())
        .addKeepMainRule(DEFAULT_CLASS_NAME)
        .setMinApi(parameters.getRuntime())
        .run(parameters.getRuntime(), DEFAULT_CLASS_NAME)
        .assertSuccessWithOutput(builders.getSecond().toString())
        .inspect(inspector -> {
          ClassSubject main = inspector.clazz(DEFAULT_CLASS_NAME);
          assertThat(main, isPresent());
          MethodSubject method = main.uniqueMethodWithName(DEFAULT_METHOD_NAME);
          assertThat(method, isPresent());
          assertTrue(method.streamInstructions().anyMatch(InstructionSubject::isJumboString));
        });
  }

  @Test
  public void test_addconfigurationdebugging() throws Exception {
    SmaliBuilder smaliBuilder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    smaliBuilder.addStaticMethod(
        "java.lang.String",
        DEFAULT_METHOD_NAME,
        ImmutableList.of(),
        2,
        builders.getFirst().toString()
    );

    // Intentionally dead code, but will be kept due to -addconfigurationdebugging.
    smaliBuilder.addStaticMethod(
        "java.lang.String",
        DEFAULT_METHOD_NAME + "2",
        ImmutableList.of(),
        2,
        builders.getFirst().toString()
    );

    smaliBuilder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    invoke-static       {}, LTest;->method()Ljava/lang/String;",
        "    move-result-object  v1",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    return-void"
    );

    testForR8(parameters.getBackend())
        .addProgramDexFileData(smaliBuilder.compile())
        .addKeepMainRule(DEFAULT_CLASS_NAME)
        .addKeepRules("-addconfigurationdebugging")
        .setMinApi(parameters.getRuntime())
        .run(parameters.getRuntime(), DEFAULT_CLASS_NAME)
        .assertSuccessWithOutput(builders.getSecond().toString())
        .inspect(inspector -> {
          ClassSubject main = inspector.clazz(DEFAULT_CLASS_NAME);
          assertThat(main, isPresent());
          MethodSubject method = main.uniqueMethodWithName(DEFAULT_METHOD_NAME);
          assertThat(method, isPresent());
          assertTrue(method.streamInstructions().anyMatch(InstructionSubject::isJumboString));
          MethodSubject method2 = main.uniqueMethodWithName(DEFAULT_METHOD_NAME + "2");
          assertThat(method2, isPresent());
          assertTrue(method2.streamInstructions().anyMatch(InstructionSubject::isJumboString));
        });
  }
}
