// 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 com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessages;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.jasmin.JasminBuilder.ClassFileVersion;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class InvalidDebugInfoTests extends TestBase {

  @Parameters(name = "{0}, strict:{1}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build(),
        BooleanUtils.values());
  }

  private final TestParameters parameters;
  private final boolean strict;

  public InvalidDebugInfoTests(TestParameters parameters, boolean strict) {
    this.parameters = parameters;
    this.strict = strict;
  }

  private void optionsModification(InternalOptions options) {
    options.invalidDebugInfoStrict = strict;
    options.testing.forceIRForCfToCfDesugar = true;
  }

  private void assertInvalidTypeMessage(TestDiagnosticMessages diagnostics) {
    assertInvalidInfoMessages(diagnostics, "Attempt to define local of type");
  }

  private void assertUninitializedLocalMessage(TestDiagnosticMessages diagnostics) {
    assertInvalidInfoMessages(diagnostics, "Local refers to uninitialized register");
  }

  private void assertInvalidInfoMessages(TestDiagnosticMessages diagnostics, String message) {
    if (parameters.isCfRuntime()) {
      diagnostics.assertNoErrors();
      diagnostics.assertWarningsMatch(cfD8NotSupportedDiagnostic);
    } else {
      diagnostics.assertOnlyInfos();
    }
    // The reporting of invalid debug info issues three info items:
    diagnostics.assertInfosMatch(
        ImmutableList.of(
            diagnosticMessage(containsString("Stripped invalid locals information")),
            diagnosticMessage(containsString(message)),
            diagnosticMessage(containsString("sign of using an outdated Java toolchain"))));
  }

  private void assertNoMessages(TestDiagnosticMessages diagnostics) {
    if (parameters.isCfRuntime()) {
      diagnostics.assertOnlyWarnings();
      diagnostics.assertWarningsMatch(cfD8NotSupportedDiagnostic);
    } else {
      diagnostics.assertNoMessages();
    }
  }

  // This is a regression test for invalid live-ranges of locals generated by some old Java
  // compilers. The issue is that a local slot may have been initialized outside the live-scope of
  // the variable and then the subsequent live-scope of the variable extends beyond its actual
  // liveness. In the example below the variable 'y' is initialized outside its range (it is thus
  // associated with the local 'x' (the SSA value is unaffected by the istore). Finally the 'return'
  // forces a read of all supposedly live variables before exiting. Here the attempt to read 'y'
  // will actually be a read of 'x'.
  @Test
  public void testInvalidInfoThrow() throws Exception {
    JasminBuilder builder = new JasminBuilder(ClassFileVersion.JDK_1_4);
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");

    clazz.addStaticMethod("foo", ImmutableList.of("I"), "V",
        ".limit stack 3",
        ".limit locals 4",
        ".var 0 is x I from LabelInit to LabelExit",
        ".var 1 is y I from LabelLocalStart to LabelExit",
        ".var 2 is e Ljava/lang/Exception; from LabelCatchStart to LabelCatchEnd",
        // var 3 is the jsr address
        "LabelInit:",
        "LabelTryStart:",
        "  ldc 84",
        "  iload 0",
        "  dup",
        "  istore 1", // init local[1] to value of local[0] (eg, 'x' since 'y' is not live yet).
        "  idiv",
        "  istore 0",
        "LabelLocalStart:",
        "  jsr LabelPrint",
        "  goto LabelExit",
        "LabelTryEnd:",
        "LabelCatchStart:",
        "  astore 2",
        "  jsr LabelPrint",
        "  return", // y is not actually live here.
        "LabelCatchEnd:",
        "LabelPrint:",
        "  astore 3",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  iload 0",
        "  invokevirtual java/io/PrintStream/println(I)V",
        "  ret 3",
        "LabelExit:",
        "  return",
        ".catch java/lang/Exception from LabelTryStart to LabelTryEnd using LabelCatchStart"
    );

    clazz.addMainMethod(
        ".limit stack 1",
        ".limit locals 1",
        "  ldc 2",
        "  invokestatic Test/foo(I)V",
        "  ldc 0",
        "  invokestatic Test/foo(I)V",
        "  return");

    String expected = "42" + ToolHelper.LINE_SEPARATOR + "0" + ToolHelper.LINE_SEPARATOR;
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .setMinApi(parameters.getApiLevel())
        .addOptionsModification(this::optionsModification)
        .compileWithExpectedDiagnostics(
            diagnostics -> {
              if (strict) {
                assertUninitializedLocalMessage(diagnostics);
              } else {
                assertNoMessages(diagnostics);
              }
            })
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected);
  }

  // Regression test to check that we properly add UninitializedLocal SSA values for methods that
  // have arguments without local info. To witness this bug, we also need "invalid" debug info, eg,
  // in this test the scope of "y" (local 2) spans the exceptional edge in which it is not live.
  @Test
  public void testInvalidInfoBug37722432() throws Exception {
    JasminBuilder builder = new JasminBuilder(ClassFileVersion.JDK_1_4);
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");

    clazz.addStaticMethod("foo", ImmutableList.of("I", "I"), "V",
        ".limit stack 2",
        ".limit locals 3",
        ".var 0 is x I from LabelInit to LabelExit",
        // Synthesized arg (no local info)
        ".var 2 is y I from LabelLocalStart to LabelExit",
        ".catch java/lang/Exception from LabelInit to LabelCatch using LabelCatch",
        "LabelInit:", // Start of try block targets catch with a state excluding 'y'.
        "  ldc 84",
        "  iload 0",
        "  idiv",
        "  istore 2",
        "LabelLocalStart:",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  iload 2",
        "  invokevirtual java/io/PrintStream/println(I)V",
        "  return",
        "LabelCatch:", // Catch target appears to include 'y' but actually does not.
        "  pop",
        "  return",
        "LabelExit:"
    );

    clazz.addMainMethod(
        ".limit stack 2",
        ".limit locals 1",
        "  ldc 2",
        "  ldc 2",
        "  invokestatic Test/foo(II)V",
        "  ldc 0",
        "  ldc 0",
        "  invokestatic Test/foo(II)V",
        "  return");

    String expected = "42" + ToolHelper.LINE_SEPARATOR;
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .addOptionsModification(this::optionsModification)
        .setMinApi(parameters.getApiLevel())
        .compileWithExpectedDiagnostics(
            diagnostics -> {
              if (strict) {
                assertUninitializedLocalMessage(diagnostics);
              } else {
                assertNoMessages(diagnostics);
              }
            })
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected);
  }

  @Test
  public void invalidInfoBug63412730_onWrite() throws Throwable {
    JasminBuilder builder = new JasminBuilder();
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
    MethodSignature method = clazz.addStaticMethod("bar", ImmutableList.of(), "V",
        ".limit stack 3",
        ".limit locals 2",
        ".var 1 is i I from LI to End",
        ".var 0 is f F from LF to End",
        "Init:",
        "  ldc 42",
        "  istore 0",
        ".line 1",
        "LI:",
        "  ldc 7.5",
        "  fstore 1",
        ".line 2",
        "LF:",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  dup",
        "  iload 0",
        "  invokevirtual java/io/PrintStream/println(I)V",
        "  fload 1",
        "  invokevirtual java/io/PrintStream/println(F)V",
        ".line 3",
        "  return",
        "End:");

    clazz.addMainMethod(
        ".limit stack 1",
        ".limit locals 1",
        "  invokestatic Test/bar()V",
        "  return");

    String expected = StringUtils.lines("42", "7.5");
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .setMinApi(parameters.getApiLevel())
        .addOptionsModification(this::optionsModification)
        .compileWithExpectedDiagnostics(
            diagnostics -> {
              if (strict) {
                assertUninitializedLocalMessage(diagnostics);
              } else {
                assertInvalidTypeMessage(diagnostics);
              }
            })
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected)
        .inspect(
            inspector ->
                assertFalse(inspector.clazz(clazz.name).method(method).hasLocalVariableTable()));
  }

  @Test
  public void invalidInfoBug63412730_onRead() throws Throwable {
    JasminBuilder builder = new JasminBuilder();
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
    MethodSignature method = clazz.addStaticMethod("bar", ImmutableList.of(), "V",
        ".limit stack 3",
        ".limit locals 2",
        ".var 1 is i I from Locals to End",
        ".var 0 is f F from Locals to End",
        "Init:",
        "  ldc 42",
        "  istore 0",
        ".line 1",
        "  ldc 7.5",
        "  fstore 1",
        ".line 2",
        "Locals:",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  dup",
        "  iload 0",
        "  invokevirtual java/io/PrintStream/println(I)V",
        "  fload 1",
        "  invokevirtual java/io/PrintStream/println(F)V",
        ".line 3",
        "  return",
        "End:");

    clazz.addMainMethod(
        ".limit stack 1",
        ".limit locals 1",
        "  invokestatic Test/bar()V",
        "  return");

    String expected = StringUtils.lines("42", "7.5");
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .addOptionsModification(this::optionsModification)
        .setMinApi(parameters.getApiLevel())
        .compileWithExpectedDiagnostics(this::assertInvalidTypeMessage)
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected)
        .inspect(
            inspector ->
                assertFalse(inspector.clazz(clazz.name).method(method).hasLocalVariableTable()));
  }

  @Test
  public void invalidInfoBug63412730_onMove() throws Throwable {
    JasminBuilder builder = new JasminBuilder(ClassFileVersion.JDK_1_4);
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
    MethodSignature method = clazz.addStaticMethod("bar", ImmutableList.of(), "V",
        ".limit stack 3",
        ".limit locals 2",
        ".var 1 is i I from LI to End",
        ".var 0 is j F from LJ to End",
        "Init:",
        "  ldc 42",
        "  istore 0",
        ".line 1",
        "LI:",
        "  ldc 0",
        "  ldc 0",
        "  ifeq LZ",
        "  ldc 75",
        "  istore 1",
        ".line 2",
        "LJ:",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  iload 1",
        "  invokevirtual java/io/PrintStream/println(I)V",
        ".line 3",
        "  return",
        "LZ:",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  iload 0",
        "  invokevirtual java/io/PrintStream/println(I)V",
        ".line 4",
        "  return",
        "End:");

    clazz.addMainMethod(
        ".limit stack 1",
        ".limit locals 1",
        "  invokestatic Test/bar()V",
        "  return");

    String expected = StringUtils.lines("42");
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .addOptionsModification(this::optionsModification)
        .setMinApi(parameters.getApiLevel())
        .compileWithExpectedDiagnostics(
            diagnostics -> {
              if (strict) {
                assertUninitializedLocalMessage(diagnostics);
              } else {
                assertInvalidTypeMessage(diagnostics);
              }
            })
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected)
        .inspect(
            inspector ->
                assertFalse(inspector.clazz(clazz.name).method(method).hasLocalVariableTable()));
  }

  @Test
  public void invalidInfoBug63412730_onPop() throws Throwable {
    JasminBuilder builder = new JasminBuilder();
    JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
    MethodSignature method = clazz.addStaticMethod("bar", ImmutableList.of(), "V",
        ".limit stack 3",
        ".limit locals 2",
        ".var 1 is a [Ljava/lang/Object; from Locals to End",
        ".var 0 is o LObject; from Locals to End",
        "Init:",
        "  ldc 1",
        "  anewarray java/lang/Object",
        "  astore 0",
        ".line 1",
        "  new java/lang/Integer",
        "  dup",
        "  ldc 42",
        "  invokespecial java/lang/Integer/<init>(I)V",
        "  astore 1",
        ".line 2",
        "Locals:",
        "  aload 0",
        "  ldc 0",
        "  aload 1",
        "  aastore",
        ".line 3",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        "  aload 0",
        "  ldc 0",
        "  aaload",
        "  invokevirtual java/io/PrintStream/println(Ljava/lang/Object;)V",
        ".line 4",
        "  return",
        "End:");

    clazz.addMainMethod(
        ".limit stack 1",
        ".limit locals 1",
        "  invokestatic Test/bar()V",
        "  return");

    String expected = StringUtils.lines("42");
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClassFileData(builder.buildClasses())
          .run(parameters.getRuntime(), clazz.name)
          .assertSuccessWithOutput(expected);
    }
    testForD8(parameters.getBackend())
        .addProgramClassFileData(builder.buildClasses())
        .addOptionsModification(this::optionsModification)
        .setMinApi(parameters.getApiLevel())
        .compileWithExpectedDiagnostics(this::assertNoMessages)
        .run(parameters.getRuntime(), clazz.name)
        .assertSuccessWithOutput(expected)
        .inspect(
            inspector -> {
              // Note: This code is actually invalid debug info, but we do not reject it because
              // both types are reference types. If we change that we should update this test.
              assertTrue(inspector.clazz(clazz.name).method(method).hasLocalVariableTable());
            });
  }
}
