// 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.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.code.IfEqz;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.debuginfo.DebugInfoInspector;
import com.android.tools.r8.graph.DexDebugEntry;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.utils.AndroidApp;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import org.apache.harmony.jpda.tests.framework.jdwp.Value;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class SmaliDebugTest extends DebugTestBase {

  static final String FILE = "SmaliDebugTestDebuggee.smali";
  static final String CLASS = "SmaliDebugTestDebuggee";

  @Rule
  public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();

  /**
   * Simple test to check setup works for the Java source, ala:
   *
   * static int method(int x) {
   *   if (x != 0) {
   *     return x
   *   } else {
   *     return 42;
   *   }
   * }
   */
  @Test
  public void testSimpleIf() throws Throwable {
    String methodName = "simpleIf";
    runDebugTest(
        new DexDebugTestConfig(buildSimpleIf(methodName)),
        CLASS,
        breakpoint(CLASS, methodName),
        run(),
        // first call x == 0
        checkLine(FILE, 1),
        checkLocal("x", Value.createInt(0)),
        stepOver(),
        checkLine(FILE, 4),
        run(),
        // second call x == 1
        checkLine(FILE, 1),
        checkLocal("x", Value.createInt(1)),
        stepOver(),
        checkLine(FILE, 2),
        run());
  }

  private List<Path> buildSimpleIf(String methodName)
      throws Throwable {
    SmaliBuilder builder = new SmaliBuilder();
    builder.addClass(CLASS);
    builder.setSourceFile(FILE);
    builder.addStaticMethod("int", methodName, Collections.singletonList("int"), 0,
        ".param p0, \"x\"    # I",
        ".line 1",
        "    if-eqz p0, :onzero",
        ".line 2",
        "    return p0",
        ":onzero",
        ".line 4",
        "    const p0, 42",
        "    return p0");

    builder.addMainMethod(2,
        "    const v0, 0",
        "    invoke-static       { v0 }, L" + CLASS + ";->" + methodName + "(I)I",
        "    move-result         v1",
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(I)V",
        "    const v0, 1",
        "    invoke-static       { v0 }, L" + CLASS + ";->" + methodName + "(I)I",
        "    move-result         v1",
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(I)V",
        "    return-void"
    );
    return buildAndRun(builder);
  }

  /**
   * Test that a jump to a position that happens after a "default" debug event still triggers a
   * break point due to the line change.
   */
  @Test
  public void testJumpAfterLineChange() throws Throwable {
    String methodName = "jumpAfterLineChange";
    List<Path> outs = buildJumpAfterLineChange(methodName);

    // Verify that the PC associated with the line entry 4 is prior to the target of the condition.
    DebugInfoInspector info =
        new DebugInfoInspector(
            AndroidApp.builder().addProgramFiles(outs).build(),
            CLASS,
            new MethodSignature(methodName, "int", new String[] {"int"}));
    IfEqz cond = null;
    for (Instruction instruction : info.getMethod().getCode().asDexCode().instructions) {
      if (instruction.getOpcode() == IfEqz.OPCODE) {
        cond = (IfEqz) instruction;
        break;
      }
    }
    assertNotNull(cond);
    int target = cond.getTargets()[0] + cond.getOffset();
    int linePC = -1;
    for (DexDebugEntry entry : info.getEntries()) {
      if (entry.line == 4) {
        linePC = entry.address;
        break;
      }
    }
    assertTrue(linePC > -1);
    assertTrue(target > linePC);

    // Run debugger to verify that we step to line 4 and the values of v0 and v1 are unchanged.
    runDebugTest(
        new DexDebugTestConfig(outs),
        CLASS,
        breakpoint(CLASS, methodName),
        run(),
        // first call x == 0
        checkLine(FILE, 1),
        checkLocal("x", Value.createInt(0)),
        checkNoLocal("v0"),
        checkNoLocal("v1"),
        stepOver(),
        checkLine(FILE, 4),
        checkLocal("v0", Value.createInt(0)),
        checkLocal("v1", Value.createInt(7)),
        stepOver(),
        checkLine(FILE, 5),
        checkLocal("v0", Value.createInt(42)),
        checkLocal("v1", Value.createInt(7)),
        run(),
        // second call x == 1
        checkLine(FILE, 1),
        checkLocal("x", Value.createInt(1)),
        checkNoLocal("v0"),
        checkNoLocal("v1"),
        stepOver(),
        checkLine(FILE, 2),
        checkNoLocal("v0"),
        checkNoLocal("v1"),
        run());
  }

  private List<Path> buildJumpAfterLineChange(String methodName)
      throws Throwable {
    SmaliBuilder builder = new SmaliBuilder();
    builder.addClass(CLASS);
    builder.setSourceFile(FILE);
    builder.addStaticMethod("int", methodName, Collections.singletonList("int"), 2,
        ".param p0, \"x\"    # I",
        ".line 1",
        "    const v0, 0",
        "    const v1, 7",
        "    if-eqz p0, :onzero",
        ".line 2",
        "    return p0",
        ".line 4",
        ".local v0, \"v0\":I",
        ".local v1, \"v1\":I",
        "    const v0, 1234", // odd and unreachable code
        "    const v1, 5678", // ...
        ":onzero",
        "    const v0, 42",
        ".line 5",
        "    return v0");

    builder.addMainMethod(2,
        "    const v0, 0",
        "    invoke-static       { v0 }, L" + CLASS + ";->" + methodName + "(I)I",
        "    move-result         v1",
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(I)V",
        "    const v0, 1",
        "    invoke-static       { v0 }, L" + CLASS + ";->" + methodName + "(I)I",
        "    move-result         v1",
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(I)V",
        "    return-void"
    );
    return buildAndRun(builder);
  }

  private List<Path> buildAndRun(SmaliBuilder builder) throws Throwable {
    byte[] bytes = builder.compile();
    Path out = temp.getRoot().toPath().resolve("classes.dex");
    Files.write(out, bytes);
    ToolHelper.runArtNoVerificationErrors(out.toString(), CLASS);
    return Collections.singletonList(out);
  }
}
