// Copyright (c) 2013, the Dart 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.

#include "vm/debugger.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_api_message.h"
#include "vm/message.h"
#include "vm/unit_test.h"

namespace dart {

#ifndef PRODUCT

DECLARE_FLAG(bool, background_compilation);
DECLARE_FLAG(bool, enable_inlining_annotations);
DECLARE_FLAG(bool, prune_dead_locals);
DECLARE_FLAG(bool, remove_script_timestamps_for_test);
DECLARE_FLAG(bool, trace_rewind);
DECLARE_FLAG(int, optimization_counter_threshold);

// Search for the formatted string in buffer.
//
// TODO(turnidge): This function obscures the line number of failing
// EXPECTs.  Rework this.
static void ExpectSubstringF(const char* buff, const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  intptr_t len = OS::VSNPrint(NULL, 0, fmt, args);
  va_end(args);

  char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1);
  va_list args2;
  va_start(args2, fmt);
  OS::VSNPrint(buffer, (len + 1), fmt, args2);
  va_end(args2);

  EXPECT_SUBSTRING(buffer, buff);
}

TEST_CASE(Debugger_GetBreakpointsById) {
  const char* kScriptChars =
      "main() {\n"
      "  var x = new StringBuffer();\n"
      "  x.add('won');\n"
      "  x.add('too');\n"
      "  return x.toString();\n"
      "}\n";
  SetFlagScope<bool> sfs(&FLAG_remove_script_timestamps_for_test, true);
  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
  EXPECT_VALID(lib);

  Isolate* isolate = Isolate::Current();
  Debugger* debugger = isolate->debugger();

  // Test with one loaded breakpoint, one latent breakpoint.
  Dart_Handle url = NewString(TestCase::url());
  Dart_Handle result = Dart_SetBreakpoint(url, 2);
  EXPECT_VALID(result);
  EXPECT(Dart_IsInteger(result));
  int64_t bp_id1 = 0;
  EXPECT_VALID(Dart_IntegerToInt64(result, &bp_id1));

  result = Dart_SetBreakpoint(NewString("not_yet_loaded_script_uri"), 4);
  EXPECT_VALID(result);
  EXPECT(Dart_IsInteger(result));
  int64_t bp_id2 = 0;
  EXPECT_VALID(Dart_IntegerToInt64(result, &bp_id2));

  EXPECT(debugger->GetBreakpointById(bp_id1) != NULL);
  EXPECT(debugger->GetBreakpointById(bp_id2) != NULL);
}

static int closure_hit_count = 0;
int64_t closure_bp_id[4];
static void PausedInClosuresHandler(Dart_IsolateId isolate_id,
                                    intptr_t bp_id,
                                    const Dart_CodeLocation& location) {
  EXPECT(bp_id == closure_bp_id[closure_hit_count]);
  closure_hit_count++;
}

TEST_CASE(Debugger_SetBreakpointInPartOfLibrary) {
  const char* kMainScript = "main() {}\n";
  const char* kLib = "library test_lib;\n";
  const char* kLibPart =
      "part of test_lib;\n"
      "void func(int a, int b) {\n"
      "  return a + b;\n"
      "}\n";
  SetFlagScope<bool> sfs(&FLAG_remove_script_timestamps_for_test, true);
  Dart_Handle root_lib = TestCase::LoadTestScript(kMainScript, NULL);
  EXPECT_VALID(root_lib);

  Dart_Handle url = NewString("test_lib_url");
  Dart_Handle lib_source = NewString(kLib);
  Dart_Handle lib = Dart_LoadLibrary(url, Dart_Null(), lib_source, 0, 0);
  EXPECT_VALID(lib);
  EXPECT(Dart_IsLibrary(lib));

  Dart_Handle part_url = NewString("part_url");
  Dart_Handle part_source = NewString(kLibPart);
  Dart_Handle result =
      Dart_LoadSource(lib, part_url, Dart_Null(), part_source, 0, 0);
  EXPECT_VALID(result);
  EXPECT(Dart_IsLibrary(result));
  EXPECT(Dart_IdentityEquals(lib, result));

  result = Dart_SetBreakpoint(part_url, 3);
  EXPECT_VALID(result);
  EXPECT(Dart_IsInteger(result));
}

TEST_CASE(Debugger_SetBreakpointInFunctionLiteralFieldInitializers) {
  const char* kScriptChars =
      "main() {\n"
      "  var c = new MyClass();\n"
      "  c.closure(1, 2);\n"
      "  MyClass.staticClosure(7, 8);\n"
      "  closure(3, 4);\n"
      "  closureSingleLine(5, 6);\n"
      "}\n"
      "class MyClass {\n"
      "  var closure = (int a, int b) {\n"
      "    return a + b;\n"
      "  };\n"
      "  static var staticClosure = (int a, int b) {\n"
      "    return a * b;\n"
      "  };\n"
      "}\n"
      "var closure = (int a, int b) {\n"
      "  return a + b;\n"
      "};\n"
      "var closureSingleLine = (int a, int b) => a * b;\n"
      "int v = 10;\n";
  SetFlagScope<bool> sfs(&FLAG_remove_script_timestamps_for_test, true);
  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
  EXPECT_VALID(lib);

  Isolate* isolate = Isolate::Current();
  Debugger* debugger = isolate->debugger();

  Dart_Handle url = NewString(TestCase::url());
  Dart_Handle result = Dart_SetBreakpoint(url, 10);
  EXPECT_VALID(result);
  EXPECT(Dart_IsInteger(result));
  EXPECT_VALID(Dart_IntegerToInt64(result, &closure_bp_id[0]));

  result = Dart_SetBreakpoint(url, 13);
  EXPECT_VALID(result);
  EXPECT(Dart_IsInteger(result));
  EXPECT_VALID(Dart_IntegerToInt64(result, &closure_bp_id[1]));

  result = Dart_SetBreakpoint(url, 17);
  EXPECT_VALID(result);
  EXPECT(Dart_IsInteger(result));
  EXPECT_VALID(Dart_IntegerToInt64(result, &closure_bp_id[2]));

  result = Dart_SetBreakpoint(url, 19);
  EXPECT_VALID(result);
  EXPECT(Dart_IsInteger(result));
  EXPECT_VALID(Dart_IntegerToInt64(result, &closure_bp_id[3]));

  // Cannot set breakpoint at the start of the class definition.
  // The implicit constructor token position matches that of the
  // class definition's token position. So, we do not want to
  // allow setting breakpoints in implicit consturctors.
  result = Dart_SetBreakpoint(url, 8);
  EXPECT_ERROR(result, "could not set breakpoint at line 8");

  result = Dart_SetBreakpoint(url, 20);
  EXPECT_ERROR(result, "could not set breakpoint at line 20");

  EXPECT(debugger->GetBreakpointById(closure_bp_id[0]) != NULL);
  EXPECT(debugger->GetBreakpointById(closure_bp_id[1]) != NULL);
  EXPECT(debugger->GetBreakpointById(closure_bp_id[2]) != NULL);
  EXPECT(debugger->GetBreakpointById(closure_bp_id[3]) != NULL);

  Dart_SetPausedEventHandler(PausedInClosuresHandler);
  result = Dart_Invoke(lib, NewString("main"), 0, NULL);
  EXPECT_VALID(result);
  EXPECT(closure_hit_count == 4);
}

TEST_CASE(Debugger_RemoveBreakpoint) {
  const char* kScriptChars =
      "main() {\n"
      "  var x = new StringBuffer();\n"
      "  x.add('won');\n"
      "  x.add('too');\n"
      "  return x.toString();\n"
      "}\n";
  SetFlagScope<bool> sfs(&FLAG_remove_script_timestamps_for_test, true);
  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
  EXPECT_VALID(lib);

  Isolate* isolate = Isolate::Current();
  Debugger* debugger = isolate->debugger();

  // Test with one loaded breakpoint, one latent breakpoint.
  Dart_Handle url = NewString(TestCase::url());
  Dart_Handle result = Dart_SetBreakpoint(url, 2);
  EXPECT_VALID(result);
  EXPECT(Dart_IsInteger(result));
  int64_t bp_id1 = 0;
  EXPECT_VALID(Dart_IntegerToInt64(result, &bp_id1));

  result = Dart_SetBreakpoint(NewString("not_yet_loaded_script_uri"), 4);
  EXPECT_VALID(result);
  EXPECT(Dart_IsInteger(result));
  int64_t bp_id2 = 0;
  EXPECT_VALID(Dart_IntegerToInt64(result, &bp_id2));

  EXPECT(debugger->GetBreakpointById(bp_id1) != NULL);
  EXPECT(debugger->GetBreakpointById(bp_id2) != NULL);

  debugger->RemoveBreakpoint(bp_id1);
  debugger->RemoveBreakpoint(bp_id2);

  EXPECT(debugger->GetBreakpointById(bp_id1) == NULL);
  EXPECT(debugger->GetBreakpointById(bp_id2) == NULL);
}

TEST_CASE(Debugger_PrintBreakpointsToJSONArray) {
  const char* kScriptChars =
      "main() {\n"
      "  var x = new StringBuffer();\n"
      "  x.add('won');\n"
      "  x.add('too');\n"
      "  return x.toString();\n"
      "}\n";
  SetFlagScope<bool> sfs(&FLAG_remove_script_timestamps_for_test, true);
  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
  EXPECT_VALID(lib);
  Library& vmlib = Library::Handle();
  vmlib ^= Api::UnwrapHandle(lib);
  EXPECT(!vmlib.IsNull());
  const String& private_key = String::Handle(vmlib.private_key());

  Isolate* isolate = Isolate::Current();
  Debugger* debugger = isolate->debugger();

  // Empty case.
  {
    JSONStream js;
    {
      JSONArray jsarr(&js);
      debugger->PrintBreakpointsToJSONArray(&jsarr);
    }
    EXPECT_STREQ("[]", js.ToCString());
  }

  // Test with a couple of loaded breakpoints, one latent breakpoint.
  Dart_Handle url = NewString(TestCase::url());
  EXPECT_VALID(Dart_SetBreakpoint(url, 2));
  EXPECT_VALID(Dart_SetBreakpoint(url, 3));
  EXPECT_VALID(Dart_SetBreakpoint(NewString("not_yet_loaded_script_uri"), 4));
  {
    JSONStream js;
    {
      JSONArray jsarr(&js);
      debugger->PrintBreakpointsToJSONArray(&jsarr);
    }
    ExpectSubstringF(
        js.ToCString(),
        "[{\"type\":\"Breakpoint\",\"fixedId\":true,\"id\":\"breakpoints\\/"
        "2\",\"breakpointNumber\":2,\"resolved\":false,\"location\":{\"type\":"
        "\"UnresolvedSourceLocation\",\"script\":{\"type\":\"@Script\","
        "\"fixedId\":true,\"id\":\"libraries\\/%s\\/scripts\\/"
        "test-lib\\/"
        "0\",\"uri\":\"test-lib\",\"_kind\":\"script\"},\"line\":3}},{\"type\":"
        "\"Breakpoint\",\"fixedId\":true,\"id\":\"breakpoints\\/"
        "1\",\"breakpointNumber\":1,\"resolved\":false,\"location\":{\"type\":"
        "\"UnresolvedSourceLocation\",\"script\":{\"type\":\"@Script\","
        "\"fixedId\":true,\"id\":\"libraries\\/%s\\/scripts\\/"
        "test-lib\\/"
        "0\",\"uri\":\"test-lib\",\"_kind\":\"script\"},\"line\":2}},{\"type\":"
        "\"Breakpoint\",\"fixedId\":true,\"id\":\"breakpoints\\/"
        "3\",\"breakpointNumber\":3,\"resolved\":false,\"location\":{\"type\":"
        "\"UnresolvedSourceLocation\",\"scriptUri\":\"not_yet_loaded_script_"
        "uri\",\"line\":4}}]",
        private_key.ToCString(), private_key.ToCString());
  }
}

static bool saw_paused_event = false;

static void InspectPausedEvent(Dart_IsolateId isolate_id,
                               intptr_t bp_id,
                               const Dart_CodeLocation& loc) {
  Isolate* isolate = Isolate::Current();
  Debugger* debugger = isolate->debugger();

  // The debugger knows that it is paused, and why.
  EXPECT(debugger->IsPaused());
  const ServiceEvent* event = debugger->PauseEvent();
  EXPECT(event != NULL);
  EXPECT(event->kind() == ServiceEvent::kPauseBreakpoint);
  saw_paused_event = true;
}

TEST_CASE(Debugger_PauseEvent) {
  const char* kScriptChars =
      "main() {\n"
      "  var x = new StringBuffer();\n"
      "  x.write('won');\n"
      "  x.write('too');\n"
      "  return x.toString();\n"
      "}\n";
  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
  EXPECT_VALID(lib);

  Isolate* isolate = Isolate::Current();
  Debugger* debugger = isolate->debugger();

  // No pause event.
  EXPECT(!debugger->IsPaused());
  EXPECT(debugger->PauseEvent() == NULL);

  saw_paused_event = false;
  Dart_SetPausedEventHandler(InspectPausedEvent);

  // Set a breakpoint and run.
  EXPECT_VALID(Dart_SetBreakpoint(NewString(TestCase::url()), 2));
  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
  EXPECT_VALID(result);
  EXPECT(Dart_IsString(result));

  // We ran the code in InspectPausedEvent.
  EXPECT(saw_paused_event);
}

static uint8_t* malloc_allocator(uint8_t* ptr,
                                 intptr_t old_size,
                                 intptr_t new_size) {
  void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
  return reinterpret_cast<uint8_t*>(new_ptr);
}

const char* rewind_frame_index = "-1";

// Build and send a fake resume OOB message for testing purposes.
void SendResumeMessage(Isolate* isolate) {
  // Format is: [ oob_type, port, seq, method_name, [keys], [values] ]
  Dart_CObject msg;
  Dart_CObject* list_values[6];
  msg.type = Dart_CObject_kArray;
  msg.value.as_array.length = 6;
  msg.value.as_array.values = list_values;

  Dart_CObject oob;
  oob.type = Dart_CObject_kInt32;
  oob.value.as_int32 = Message::kServiceOOBMsg;
  list_values[0] = &oob;

  Dart_CObject reply_port;
  reply_port.type = Dart_CObject_kNull;
  list_values[1] = &reply_port;

  Dart_CObject seq;
  seq.type = Dart_CObject_kNull;
  list_values[2] = &seq;

  Dart_CObject method_name;
  method_name.type = Dart_CObject_kString;
  method_name.value.as_string = const_cast<char*>("resume");
  list_values[3] = &method_name;

  const int kParamCount = 3;
  Dart_CObject param_keys;
  Dart_CObject* param_keys_list[kParamCount];
  param_keys.type = Dart_CObject_kArray;
  param_keys.value.as_array.values = param_keys_list;
  param_keys.value.as_array.length = kParamCount;
  list_values[4] = &param_keys;

  Dart_CObject param_values;
  Dart_CObject* param_values_list[kParamCount];
  param_values.type = Dart_CObject_kArray;
  param_values.value.as_array.values = param_values_list;
  param_values.value.as_array.length = kParamCount;
  list_values[5] = &param_values;

  Dart_CObject param0_name;
  param0_name.type = Dart_CObject_kString;
  param0_name.value.as_string = const_cast<char*>("isolateId");
  param_keys_list[0] = &param0_name;

  Dart_CObject param0_value;
  param0_value.type = Dart_CObject_kString;
  const char* isolate_id = Thread::Current()->zone()->PrintToString(
      ISOLATE_SERVICE_ID_FORMAT_STRING,
      static_cast<int64_t>(isolate->main_port()));
  param0_value.value.as_string = const_cast<char*>(isolate_id);
  param_values_list[0] = &param0_value;

  Dart_CObject param1_name;
  param1_name.type = Dart_CObject_kString;
  param1_name.value.as_string = const_cast<char*>("step");
  param_keys_list[1] = &param1_name;

  Dart_CObject param1_value;
  param1_value.type = Dart_CObject_kString;
  param1_value.value.as_string = const_cast<char*>("Rewind");
  param_values_list[1] = &param1_value;

  Dart_CObject param2_name;
  param2_name.type = Dart_CObject_kString;
  param2_name.value.as_string = const_cast<char*>("frameIndex");
  param_keys_list[2] = &param2_name;

  Dart_CObject param2_value;
  param2_value.type = Dart_CObject_kString;
  param2_value.value.as_string = const_cast<char*>(rewind_frame_index);
  param_values_list[2] = &param2_value;

  {
    uint8_t* buffer = NULL;
    ApiMessageWriter writer(&buffer, &malloc_allocator);
    bool success = writer.WriteCMessage(&msg);
    ASSERT(success);

    // Post the message at the given port.
    success = PortMap::PostMessage(new Message(isolate->main_port(), buffer,
                                               writer.BytesWritten(),
                                               Message::kOOBPriority));
    ASSERT(success);
  }
}

static void RewindOnce(Dart_IsolateId isolate_id,
                       intptr_t bp_id,
                       const Dart_CodeLocation& loc) {
  bool first_time = !saw_paused_event;
  saw_paused_event = true;
  if (first_time) {
    Thread* T = Thread::Current();
    Isolate* I = T->isolate();
    // TODO(turnidge): It is weird that the isolate can get to this
    // point in our tests without being marked runnable. Clear this up
    // at some point.
    I->set_is_runnable(true);
    SendResumeMessage(I);
    I->PauseEventHandler();
  }
}

TEST_CASE(Debugger_RewindOneFrame_Unoptimized) {
  SetFlagScope<bool> sfs(&FLAG_trace_rewind, true);

  // These variables are global state used by RewindOnce.
  saw_paused_event = false;
  rewind_frame_index = "1";

  const char* kScriptChars =
      "import 'dart:developer';\n"
      "\n"
      "var msg = new StringBuffer();\n"
      "\n"
      "foo() {\n"
      "  msg.write('enter(foo) ');\n"
      "  debugger();\n"
      "  msg.write('exit(foo) ');\n"
      "}\n"
      "\n"
      "main() {\n"
      "  msg.write('enter(main) ');\n"
      "  foo();\n"
      "  msg.write('exit(main) ');\n"
      "  return msg.toString();\n"
      "}\n";
  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
  EXPECT_VALID(lib);

  Dart_SetPausedEventHandler(RewindOnce);
  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
  const char* result_cstr;
  EXPECT_VALID(result);
  EXPECT(Dart_IsString(result));
  EXPECT_VALID(Dart_StringToCString(result, &result_cstr));
  EXPECT_STREQ("enter(main) enter(foo) enter(foo) exit(foo) exit(main) ",
               result_cstr);
  EXPECT(saw_paused_event);
}

TEST_CASE(Debugger_RewindTwoFrames_Unoptimized) {
  SetFlagScope<bool> sfs(&FLAG_trace_rewind, true);

  // These variables are global state used by RewindOnce.
  saw_paused_event = false;
  rewind_frame_index = "2";

  const char* kScriptChars =
      "import 'dart:developer';\n"
      "\n"
      "var msg = new StringBuffer();\n"
      "\n"
      "foo() {\n"
      "  msg.write('enter(foo) ');\n"
      "  debugger();\n"
      "  msg.write('exit(foo) ');\n"
      "}\n"
      "\n"
      "bar() {\n"
      "  msg.write('enter(bar) ');\n"
      "  foo();\n"
      "  msg.write('exit(bar) ');\n"
      "}\n"
      "\n"
      "main() {\n"
      "  msg.write('enter(main) ');\n"
      "  bar();\n"
      "  msg.write('exit(main) ');\n"
      "  return msg.toString();\n"
      "}\n";
  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
  EXPECT_VALID(lib);

  Dart_SetPausedEventHandler(RewindOnce);
  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
  const char* result_cstr;
  EXPECT_VALID(result);
  EXPECT(Dart_IsString(result));
  EXPECT_VALID(Dart_StringToCString(result, &result_cstr));
  EXPECT_STREQ(
      "enter(main) enter(bar) enter(foo) enter(bar) enter(foo) "
      "exit(foo) exit(bar) exit(main) ",
      result_cstr);
  EXPECT(saw_paused_event);
}

TEST_CASE(Debugger_Rewind_Optimized) {
  SetFlagScope<bool> sfs1(&FLAG_trace_rewind, true);
  SetFlagScope<bool> sfs2(&FLAG_prune_dead_locals, false);
  SetFlagScope<bool> sfs3(&FLAG_enable_inlining_annotations, true);
  SetFlagScope<bool> sfs4(&FLAG_background_compilation, false);
  SetFlagScope<int> sfs5(&FLAG_optimization_counter_threshold, 10);

  // These variables are global state used by RewindOnce.
  saw_paused_event = false;
  rewind_frame_index = "2";

  const char* kScriptChars =
      "import 'dart:developer';\n"
      "\n"
      "const alwaysInline = \"AlwaysInline\";\n"
      "const noInline = \"NeverInline\";\n"
      "\n"
      "var msg = new StringBuffer();\n"
      "int i;\n"
      "\n"
      "@noInline\n"
      "foo() {\n"
      "  msg.write('enter(foo) ');\n"
      "  if (i > 15) {\n"
      "    debugger();\n"
      "    msg.write('exit(foo) ');\n"
      "    return true;\n"
      "  } else {\n"
      "    msg.write('exit(foo) ');\n"
      "    return false;\n"
      "  }\n"
      "}\n"
      "\n"
      "@alwaysInline\n"
      "bar3() {\n"
      "  msg.write('enter(bar3) ');\n"
      "  var result = foo();\n"
      "  msg.write('exit(bar3) ');\n"
      "  return result;\n"
      "}\n"
      "\n"
      "@alwaysInline\n"
      "bar2() {\n"
      "  msg.write('enter(bar2) ');\n"
      "  var result = bar3();\n"
      "  msg.write('exit(bar2) ');\n"
      "  return result;\n"
      "}\n"
      "\n"
      "@alwaysInline\n"
      "bar1() {\n"
      "  msg.write('enter(bar1) ');\n"
      "  var result = bar2();\n"
      "  msg.write('exit(bar1) ');\n"
      "  return result;\n"
      "}\n"
      "\n"
      "main() {\n"
      "  for (i = 0; i < 20; i++) {\n"
      "    msg.clear();\n"
      "    if (bar1()) break;\n;"
      "  }\n"
      "  return msg.toString();\n"
      "}\n";
  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
  EXPECT_VALID(lib);

  Dart_SetPausedEventHandler(RewindOnce);
  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
  const char* result_cstr;
  EXPECT_VALID(result);
  EXPECT(Dart_IsString(result));
  EXPECT_VALID(Dart_StringToCString(result, &result_cstr));
  EXPECT_STREQ(
      "enter(bar1) enter(bar2) enter(bar3) enter(foo) "
      "enter(bar3) enter(foo) "
      "exit(foo) exit(bar3) exit(bar2) exit(bar1) ",
      result_cstr);
  EXPECT(saw_paused_event);
}

#endif  // !PRODUCT

}  // namespace dart
