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

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.debuginfo.DebugInfoInspector;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import org.junit.Test;

public class JumboStringTests extends JasminTestBase {

  // String constants are split into several class files to ensure both the constant-pool and
  // instruction count are below the class-file limits.
  private static int CLASSES_COUNT = 10;
  private static int MIN_STRING_COUNT = Constants.MAX_NON_JUMBO_INDEX + 2;
  private static int EXTRA_STRINGS_PER_CLASSES_COUNT = MIN_STRING_COUNT % CLASSES_COUNT;
  private static int STRINGS_PER_CLASSES_COUNT =
      EXTRA_STRINGS_PER_CLASSES_COUNT + MIN_STRING_COUNT / CLASSES_COUNT;

  @Test
  public void test() throws Exception {
    JasminBuilder builder = new JasminBuilder();
    LinkedHashMap<String, MethodSignature> classes = new LinkedHashMap<>(CLASSES_COUNT);
    for (int i = 0; i < CLASSES_COUNT; i++) {
      JasminBuilder.ClassBuilder clazz = builder.addClass("Test" + i);
      List<String> lines = new ArrayList<>(STRINGS_PER_CLASSES_COUNT + 100);
      lines.addAll(
          ImmutableList.of(
              ".limit locals 3",
              ".limit stack 4",
              ".var 0 is this LTest; from L0 to L2",
              ".var 1 is i I from L0 to L2",
              ".var 2 is strings [Ljava/lang/String; from L1 to L2",
              "L0:",
              ".line 1",
              "  ldc " + STRINGS_PER_CLASSES_COUNT,
              "  anewarray java/lang/String",
              "  astore 2",
              "L1:",
              ".line 2"));
      for (int j = 0; j < STRINGS_PER_CLASSES_COUNT; j++) {
        lines.add("  aload 2");
        lines.add("  ldc " + j);
        lines.add("  ldc \"string" + i + "_" + j + "\"");
        lines.add("  aastore");
      }
      lines.addAll(
          ImmutableList.of(
              "L2:",
              "  .line 3",
              "  aload 2",
              "  iload 1",
              "  aaload",
              "  checkcast java/lang/String",
              "  areturn"));
      MethodSignature foo =
          clazz.addVirtualMethod(
              "foo", ImmutableList.of("I"), "Ljava/lang/String;", lines.toArray(new String[0]));
      classes.put(clazz.name, foo);
    }

    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
    clazz.addMainMethod(
        ".limit stack 3",
        ".limit locals 1",
        "  new Test0",
        "  dup",
        "  invokespecial Test0/<init>()V",
        "  ldc 42",
        "  invokevirtual Test0/foo(I)Ljava/lang/String;",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  swap",
        "  invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
        "  return");

    String expected = "string0_42";
    assertEquals(expected, runOnJava(builder, clazz.name));

    AndroidApp jasminApp = builder.build();
    AndroidApp d8App = ToolHelper.runD8(jasminApp);
    assertEquals(expected, runOnArt(d8App, clazz.name));

    CodeInspector inspector = new CodeInspector(d8App);
    for (Entry<String, MethodSignature> entry : classes.entrySet()) {
      DebugInfoInspector info = new DebugInfoInspector(inspector, entry.getKey(), entry.getValue());
      info.checkStartLine(1);
      // If jumbo-string processing fails to keep debug info, some methods will have lost 'i' here.
      info.checkLineHasExactLocals(1, "this", entry.getKey(), "i", "int");
      info.checkLineHasExactLocals(
          2, "this", entry.getKey(), "i", "int", "strings", "java.lang.String[]");
    }
  }
}
