// 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.Diagnostic;
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.hamcrest.Matcher;
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 final Matcher<Diagnostic> cfNotSupportedDiagnostic =
      diagnosticMessage(
          containsString("Compiling to Java class files with D8 is not officially supported"));

  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(cfNotSupportedDiagnostic);
    } 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(cfNotSupportedDiagnostic);
    } 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());
            });
  }
}
