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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.apache.harmony.jpda.tests.framework.jdwp.Value;
import org.junit.Test;

// TODO check double-depth inline (an inline in another inline)
public class KotlinInlineTest extends KotlinDebugTestBase {

  @Test
  public void testStepOverInline() throws Throwable {
    String methodName = "singleInline";
    runDebugTest(
        getD8Config(),
        "KotlinInline",
        breakpoint("KotlinInline", methodName),
        run(),
        inspect(s -> {
          assertEquals("KotlinInline", s.getClassName());
          assertEquals(methodName, s.getMethodName());
          assertEquals("KotlinInline.kt", s.getSourceFile());
          assertEquals(41, s.getLineNumber());
          s.checkLocal("this");
        }),
        stepOver(),
        inspect(s -> {
          assertEquals("KotlinInline", s.getClassName());
          assertEquals(methodName, s.getMethodName());
          assertEquals("KotlinInline.kt", s.getSourceFile());
          assertEquals(42, s.getLineNumber());
          s.checkLocal("this");
        }),
        kotlinStepOver(),
        inspect(s -> {
          assertEquals("KotlinInline", s.getClassName());
          assertEquals(methodName, s.getMethodName());
          assertEquals("KotlinInline.kt", s.getSourceFile());
          assertEquals(43, s.getLineNumber());
          s.checkLocal("this");
        }),
        run());
  }

  @Test
  public void testStepIntoInline() throws Throwable {
    String methodName = "singleInline";
    runDebugTest(
        getD8Config(),
        "KotlinInline",
        breakpoint("KotlinInline", methodName),
        run(),
        inspect(s -> {
          assertEquals("KotlinInline", s.getClassName());
          assertEquals(methodName, s.getMethodName());
          assertEquals("KotlinInline.kt", s.getSourceFile());
          assertEquals(41, s.getLineNumber());
          s.checkLocal("this");
        }),
        stepOver(),
        inspect(s -> {
          assertEquals("KotlinInline", s.getClassName());
          assertEquals(methodName, s.getMethodName());
          assertEquals("KotlinInline.kt", s.getSourceFile());
          assertEquals(42, s.getLineNumber());
          s.checkLocal("this");
        }),
        stepInto(),
        inspect(s -> {
          assertEquals("KotlinInline", s.getClassName());
          assertEquals(methodName, s.getMethodName());
          assertEquals("KotlinInline.kt", s.getSourceFile());
          // The actual line number (the one encoded in debug information) is different than the
          // source file one.
          // TODO(shertz) extract original line number from JSR-45's SMAP (only supported on
          // Android O+).
          assertTrue(42 != s.getLineNumber());
          s.checkLocal("this");
        }),
        run());
  }

  @Test
  public void testStepOutInline() throws Throwable {
    String methodName = "singleInline";
    runDebugTest(
        getD8Config(),
        "KotlinInline",
        breakpoint("KotlinInline", methodName),
        run(),
        inspect(s -> {
          assertEquals("KotlinInline", s.getClassName());
          assertEquals(methodName, s.getMethodName());
          assertEquals("KotlinInline.kt", s.getSourceFile());
          assertEquals(41, s.getLineNumber());
          s.checkLocal("this");
        }),
        stepOver(),
        inspect(s -> {
          assertEquals("KotlinInline", s.getClassName());
          assertEquals(methodName, s.getMethodName());
          assertEquals("KotlinInline.kt", s.getSourceFile());
          assertEquals(42, s.getLineNumber());
          s.checkLocal("this");
        }),
        stepInto(),
        inspect(s -> {
          assertEquals("KotlinInline", s.getClassName());
          assertEquals(methodName, s.getMethodName());
        }),
        kotlinStepOut(),
        inspect(s -> {
          assertEquals("KotlinInline", s.getClassName());
          assertEquals(methodName, s.getMethodName());
          assertEquals("KotlinInline.kt", s.getSourceFile());
          assertEquals(43, s.getLineNumber());
          s.checkLocal("this");
        }),
        run());
  }

  @Test
  public void testKotlinInline() throws Throwable {
    final String inliningMethodName = "invokeInlinedFunctions";
    runDebugTest(
        getD8Config(),
        "KotlinInline",
        breakpoint("KotlinInline", inliningMethodName),
        run(),
        inspect(s -> {
          assertEquals(inliningMethodName, s.getMethodName());
          assertEquals(16, s.getLineNumber());
          s.checkLocal("this");
        }),
        stepInto(),
        inspect(s -> {
          // We must have stepped into the code of the inlined method but the actual current method
          // did not change.
          assertEquals(inliningMethodName, s.getMethodName());
          // TODO(shertz) get the original line if JSR45 is supported by the targeted ART runtime.
          s.checkLocal("this");
        }),
        stepInto(),
        inspect(s -> {
          assertEquals(inliningMethodName, s.getMethodName());
          assertEquals(17, s.getLineNumber());
          s.checkLocal("this");
        }),
        stepInto(),
        inspect(s -> {
          assertEquals(inliningMethodName, s.getMethodName());
          assertEquals(18, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("inA", Value.createInt(1));
          // This is a "hidden" lv added by Kotlin (which is neither initialized nor used).
          s.checkLocal("$i$f$inlinedA");
          s.checkLocal("$i$a$1$inlinedA");
        }),
        stepInto(),
        inspect(s -> {
          // We must have stepped into the code of the second inlined method but the actual current
          // method did not change.
          assertEquals(inliningMethodName, s.getMethodName());
          // TODO(shertz) get the original line if JSR45 is supported by the targeted ART runtime.
          s.checkLocal("this");
        }),
        stepInto(),
        inspect(s -> {
          assertEquals(inliningMethodName, s.getMethodName());
          assertEquals(19, s.getLineNumber());
          s.checkLocal("this");
        }),
        stepInto(),
        inspect(s -> {
          assertEquals(inliningMethodName, s.getMethodName());
          assertEquals(20, s.getLineNumber());
          s.checkLocal("this");
          s.checkLocal("inB", Value.createInt(2));
          // This is a "hidden" lv added by Kotlin (which is neither initialized nor used).
          s.checkLocal("$i$f$inlinedB");
          s.checkLocal("$i$a$1$inlinedB");
        }),
        run());
  }

}
