// Copyright (c) 2012, 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 "bin/dbg_connection.h"
#include "bin/dbg_message.h"
#include "bin/dartutils.h"
#include "bin/lockers.h"
#include "bin/thread.h"
#include "bin/utils.h"

#include "platform/globals.h"
#include "platform/json.h"
#include "platform/utils.h"

#include "include/dart_api.h"


namespace dart {
namespace bin {

bool MessageParser::IsValidMessage() const {
  if (buf_length_ == 0) {
    return false;
  }
  dart::JSONReader msg_reader(buf_);
  return msg_reader.EndOfObject() != NULL;
}


int MessageParser::MessageId() const {
  dart::JSONReader r(buf_);
  r.Seek("id");
  if (r.Type() == dart::JSONReader::kInteger) {
    return atoi(r.ValueChars());
  } else {
    return -1;
  }
}


const char* MessageParser::Params() const {
  dart::JSONReader r(buf_);
  r.Seek("params");
  if (r.Type() == dart::JSONReader::kObject) {
    return r.ValueChars();
  } else {
    return NULL;
  }
}


bool MessageParser::HasParam(const char* name) const {
  const char* params = Params();
  ASSERT(params != NULL);
  dart::JSONReader r(params);
  return r.Seek(name);
}


intptr_t MessageParser::GetIntParam(const char* name) const {
  const char* params = Params();
  ASSERT(params != NULL);
  dart::JSONReader r(params);
  r.Seek(name);
  ASSERT(r.Type() == dart::JSONReader::kInteger);
  return strtol(r.ValueChars(), NULL, 10);
}


int64_t MessageParser::GetInt64Param(const char* name) const {
  const char* params = Params();
  ASSERT(params != NULL);
  dart::JSONReader r(params);
  r.Seek(name);
  ASSERT(r.Type() == dart::JSONReader::kInteger);
  return strtoll(r.ValueChars(), NULL, 10);
}


intptr_t MessageParser::GetOptIntParam(const char* name,
                                       intptr_t default_val) const {
  const char* params = Params();
  ASSERT(params != NULL);
  dart::JSONReader r(params);
  r.Seek(name);
  if (r.Type() == dart::JSONReader::kInteger) {
    return strtol(r.ValueChars(), NULL, 10);
  } else {
    return default_val;
  }
}


static const char* GetStringChars(Dart_Handle str) {
  ASSERT(Dart_IsString(str));
  const char* chars;
  Dart_Handle res = Dart_StringToCString(str, &chars);
  ASSERT(!Dart_IsError(res));
  return chars;
}


static int64_t GetIntValue(Dart_Handle int_handle) {
  int64_t int64_val = -1;
  ASSERT(Dart_IsInteger(int_handle));
  Dart_Handle res = Dart_IntegerToInt64(int_handle, &int64_val);
  ASSERT_NOT_ERROR(res);
  return int64_val;
}


char* MessageParser::GetStringParam(const char* name) const {
  const char* params = Params();
  ASSERT(params != NULL);
  dart::JSONReader pr(params);
  pr.Seek(name);
  if (pr.Type() != dart::JSONReader::kString) {
    return NULL;
  }
  intptr_t buflen = pr.ValueLen() + 1;
  char* param_chars = reinterpret_cast<char*>(malloc(buflen));
  pr.GetDecodedValueChars(param_chars, buflen);
  return param_chars;
}


static void FormatEncodedCharsTrunc(dart::TextBuffer* buf,
                                    Dart_Handle str,
                                    intptr_t max_chars) {
  intptr_t str_len = 0;
  Dart_Handle res = Dart_StringLength(str, &str_len);
  ASSERT_NOT_ERROR(res);
  intptr_t num_chars = (str_len > max_chars) ? max_chars : str_len;
  uint16_t* codeunits =
      reinterpret_cast<uint16_t*>(malloc(num_chars * sizeof(uint16_t)));
  ASSERT(codeunits != NULL);
  intptr_t actual_len = num_chars;
  res = Dart_StringToUTF16(str, codeunits, &actual_len);
  ASSERT_NOT_ERROR(res);
  ASSERT(num_chars == actual_len);
  for (int i = 0; i < num_chars; i++) {
    buf->EscapeAndAddCodeUnit(codeunits[i]);
  }
  if (str_len > max_chars) {
    buf->Printf("...");
  }
  free(codeunits);
}


static void FormatEncodedChars(dart::TextBuffer* buf, Dart_Handle str) {
  intptr_t str_len = 0;
  Dart_Handle res = Dart_StringLength(str, &str_len);
  ASSERT_NOT_ERROR(res);
  uint16_t* codeunits =
      reinterpret_cast<uint16_t*>(malloc(str_len * sizeof(uint16_t)));
  ASSERT(codeunits != NULL);
  intptr_t actual_len = str_len;
  res = Dart_StringToUTF16(str, codeunits, &actual_len);
  ASSERT_NOT_ERROR(res);
  ASSERT(str_len == actual_len);
  for (int i = 0; i < str_len; i++) {
    buf->EscapeAndAddCodeUnit(codeunits[i]);
  }
  free(codeunits);
}


static void FormatEncodedString(dart::TextBuffer* buf, Dart_Handle str) {
  buf->AddChar('\"');
  FormatEncodedChars(buf, str);
  buf->AddChar('\"');
}


static void FormatTextualValue(dart::TextBuffer* buf,
                               Dart_Handle object,
                               intptr_t max_chars,
                               bool expand_list);


static void FormatTextualListValue(dart::TextBuffer* buf,
                                   Dart_Handle list,
                                   intptr_t max_chars) {
  intptr_t len = 0;
  Dart_Handle res = Dart_ListLength(list, &len);
  ASSERT_NOT_ERROR(res);
  const intptr_t initial_buffer_length = buf->length();
  // Maximum number of characters we print for array elements.
  const intptr_t max_buffer_length = initial_buffer_length + max_chars;
  buf->Printf("[");
  for (int i = 0; i < len; i++) {
    if (i > 0) {
      buf->Printf(", ");
    }
    Dart_Handle elem = Dart_ListGetAt(list, i);
    const intptr_t max_element_chars = 50;
    FormatTextualValue(buf, elem, max_element_chars, false);
    if (buf->length() > max_buffer_length) {
      buf->Printf(", ...");
      break;
    }
  }
  buf->Printf("]");
}


static void FormatTextualValue(dart::TextBuffer* buf,
                               Dart_Handle object,
                               intptr_t max_chars,
                               bool expand_list) {
  ASSERT(!Dart_IsError(object));
  if (Dart_IsList(object)) {
    if (expand_list) {
      FormatTextualListValue(buf, object, max_chars);
    } else {
      buf->Printf("[...]");
    }
  } else if (Dart_IsNull(object)) {
    buf->Printf("null");
  } else if (Dart_IsString(object)) {
    buf->Printf("\\\"");
    FormatEncodedCharsTrunc(buf, object, max_chars);
    buf->Printf("\\\"");
  } else if (Dart_IsNumber(object) || Dart_IsBoolean(object)) {
    Dart_Handle text = Dart_ToString(object);
    ASSERT(!Dart_IsNull(text) && !Dart_IsError(text));
    FormatEncodedCharsTrunc(buf, text, max_chars);
  } else {
    Dart_Handle type = Dart_InstanceGetType(object);
    ASSERT_NOT_ERROR(type);
    type = Dart_ToString(type);
    ASSERT_NOT_ERROR(type);
    buf->Printf("object of type ");
    FormatEncodedCharsTrunc(buf, type, max_chars);
  }
}


static void FormatValue(dart::TextBuffer* buf, Dart_Handle object) {
  bool print_text_field = true;
  if (Dart_IsNumber(object)) {
    buf->Printf("\"kind\":\"number\"");
  } else if (Dart_IsString(object)) {
    buf->Printf("\"kind\":\"string\"");
  } else if (Dart_IsBoolean(object)) {
    buf->Printf("\"kind\":\"boolean\"");
  } else if (Dart_IsList(object)) {
    intptr_t len = 0;
    Dart_Handle res = Dart_ListLength(object, &len);
    ASSERT_NOT_ERROR(res);
    buf->Printf("\"kind\":\"list\",\"length\":%" Pd "", len);
  } else if (Dart_IsClosure(object)) {
    Dart_Handle name, signature;
    Dart_CodeLocation location;
    Dart_Handle res = Dart_GetClosureInfo(object, &name, &signature, &location);
    ASSERT_NOT_ERROR(res);
    buf->Printf("\"kind\":\"function\",\"name\":\"%s\"", GetStringChars(name));
    buf->Printf(",\"signature\":\"%s\"", GetStringChars(signature));
    if (!Dart_IsNull(location.script_url)) {
      ASSERT(Dart_IsString(location.script_url));
      buf->Printf(",\"location\": { \"url\":");
      FormatEncodedString(buf, location.script_url);
      buf->Printf(",\"libraryId\":%d,", location.library_id);
      buf->Printf("\"tokenOffset\":%d}", location.token_pos);
    }
    print_text_field = false;
  } else {
    buf->Printf("\"kind\":\"object\"");
    intptr_t class_id = 0;
    Dart_Handle res = Dart_GetObjClassId(object, &class_id);
    if (!Dart_IsError(res)) {
      buf->Printf(",\"classId\":%" Pd "", class_id);
    }
  }
  if (print_text_field) {
    buf->Printf(",\"text\":\"");
    const intptr_t max_chars = 1024;
    FormatTextualValue(buf, object, max_chars, true);
    buf->Printf("\"");
  }
}


static void FormatValueObj(dart::TextBuffer* buf, Dart_Handle object) {
  buf->Printf("{");
  FormatValue(buf, object);
  buf->Printf("}");
}


static void FormatRemoteObj(dart::TextBuffer* buf, Dart_Handle object) {
  intptr_t obj_id = Dart_CacheObject(object);
  ASSERT(obj_id >= 0);
  buf->Printf("{\"objectId\":%" Pd ",", obj_id);
  FormatValue(buf, object);
  buf->Printf("}");
}


static void FormatNamedValue(dart::TextBuffer* buf,
                             Dart_Handle object_name,
                             Dart_Handle object) {
  ASSERT(Dart_IsString(object_name));
  buf->Printf("{\"name\":\"%s\",", GetStringChars(object_name));
  buf->Printf("\"value\":");
  FormatRemoteObj(buf, object);
  buf->Printf("}");
}


static void FormatNamedValueList(dart::TextBuffer* buf,
                                 Dart_Handle obj_list) {
  ASSERT(Dart_IsList(obj_list));
  intptr_t list_length = 0;
  Dart_Handle res = Dart_ListLength(obj_list, &list_length);
  ASSERT_NOT_ERROR(res);
  ASSERT(list_length % 2 == 0);
  buf->Printf("[");
  for (int i = 0; i + 1 < list_length; i += 2) {
    Dart_Handle name_handle = Dart_ListGetAt(obj_list, i);
    ASSERT_NOT_ERROR(name_handle);
    Dart_Handle value_handle = Dart_ListGetAt(obj_list, i + 1);
    ASSERT_NOT_ERROR(value_handle);
    if (i > 0) {
      buf->Printf(",");
    }
    FormatNamedValue(buf, name_handle, value_handle);
  }
  buf->Printf("]");
}


static const char* FormatClassProps(dart::TextBuffer* buf,
                                    intptr_t cls_id) {
  Dart_Handle name, static_fields;
  intptr_t super_id = -1;
  intptr_t library_id = -1;
  Dart_Handle res =
      Dart_GetClassInfo(cls_id, &name, &library_id, &super_id, &static_fields);
  RETURN_IF_ERROR(res);
  RETURN_IF_ERROR(name);
  buf->Printf("{\"name\":\"%s\",", GetStringChars(name));
  if (super_id > 0) {
    buf->Printf("\"superclassId\":%" Pd ",", super_id);
  }
  buf->Printf("\"libraryId\":%" Pd ",", library_id);
  RETURN_IF_ERROR(static_fields);
  buf->Printf("\"fields\":");
  FormatNamedValueList(buf, static_fields);
  buf->Printf("}");
  return NULL;
}


static const char* FormatLibraryProps(dart::TextBuffer* buf,
                                      intptr_t lib_id) {
  Dart_Handle url = Dart_GetLibraryURL(lib_id);
  RETURN_IF_ERROR(url);
  buf->Printf("{\"url\":");
  FormatEncodedString(buf, url);

  // Whether debugging is enabled.
  bool is_debuggable = false;
  Dart_Handle res = Dart_GetLibraryDebuggable(lib_id, &is_debuggable);
  RETURN_IF_ERROR(res);
  buf->Printf(",\"debuggingEnabled\":%s",
              is_debuggable ? "\"true\"" : "\"false\"");

  // Imports and prefixes.
  Dart_Handle import_list = Dart_GetLibraryImports(lib_id);
  RETURN_IF_ERROR(import_list);
  ASSERT(Dart_IsList(import_list));
  intptr_t list_length = 0;
  res = Dart_ListLength(import_list, &list_length);
  RETURN_IF_ERROR(res);
  buf->Printf(",\"imports\":[");
  for (intptr_t i = 0; i + 1 < list_length; i += 2) {
    Dart_Handle lib_id = Dart_ListGetAt(import_list, i + 1);
    ASSERT_NOT_ERROR(lib_id);
    buf->Printf("%s{\"libraryId\":%" Pd64 ",",
                (i > 0) ? ",": "",
                GetIntValue(lib_id));

    Dart_Handle name = Dart_ListGetAt(import_list, i);
    ASSERT_NOT_ERROR(name);
    buf->Printf("\"prefix\":\"%s\"}",
                Dart_IsNull(name) ? "" : GetStringChars(name));
  }
  buf->Printf("],");

  // Global variables in the library.
  Dart_Handle global_vars = Dart_GetLibraryFields(lib_id);
  RETURN_IF_ERROR(global_vars);
  buf->Printf("\"globals\":");
  FormatNamedValueList(buf, global_vars);
  buf->Printf("}");
  return NULL;
}


static const char* FormatObjProps(dart::TextBuffer* buf,
                                  Dart_Handle object) {
  intptr_t class_id;
  if (Dart_IsNull(object)) {
    buf->Printf("{\"classId\":-1,\"fields\":[]}");
    return NULL;
  }
  Dart_Handle res = Dart_GetObjClassId(object, &class_id);
  RETURN_IF_ERROR(res);
  buf->Printf("{\"classId\": %" Pd ",", class_id);
  buf->Printf("\"kind\":\"object\",\"fields\":");
  Dart_Handle fields = Dart_GetInstanceFields(object);
  RETURN_IF_ERROR(fields);
  FormatNamedValueList(buf, fields);
  buf->Printf("}");
  return NULL;
}


static const char* FormatListSlice(dart::TextBuffer* buf,
                                   Dart_Handle list,
                                   intptr_t list_length,
                                   intptr_t index,
                                   intptr_t slice_length) {
  intptr_t end_index = index + slice_length;
  ASSERT(end_index <= list_length);
  buf->Printf("{\"index\":%" Pd ",", index);
  buf->Printf("\"length\":%" Pd ",", slice_length);
  buf->Printf("\"elements\":[");
  for (intptr_t i = index; i < end_index; i++) {
    Dart_Handle value = Dart_ListGetAt(list, i);
    if (i > index) {
      buf->Printf(",");
    }
    FormatValueObj(buf, value);
  }
  buf->Printf("]}");
  return NULL;
}


static void FormatLocationFromTrace(dart::TextBuffer* msg,
                                    Dart_StackTrace trace,
                                    const char* prefix) {
  intptr_t trace_len = 0;
  Dart_Handle res = Dart_StackTraceLength(trace, &trace_len);
  ASSERT_NOT_ERROR(res);
  if (trace_len == 0) {
    return;
  }
  Dart_ActivationFrame frame;
  res = Dart_GetActivationFrame(trace, 0, &frame);
  ASSERT_NOT_ERROR(res);
  Dart_CodeLocation location;
  res = Dart_ActivationFrameGetLocation(frame, NULL, NULL, &location);
  ASSERT_NOT_ERROR(res);
  if (!Dart_IsNull(location.script_url)) {
    ASSERT(Dart_IsString(location.script_url));
    msg->Printf("%s\"location\": { \"url\":", prefix);
    FormatEncodedString(msg, location.script_url);
    msg->Printf(",\"libraryId\":%d,", location.library_id);
    msg->Printf("\"tokenOffset\":%d}", location.token_pos);
  }
}


static void FormatCallFrames(dart::TextBuffer* msg, Dart_StackTrace trace) {
  intptr_t trace_len = 0;
  Dart_Handle res = Dart_StackTraceLength(trace, &trace_len);
  ASSERT_NOT_ERROR(res);
  msg->Printf("\"callFrames\" : [ ");
  for (int i = 0; i < trace_len; i++) {
    Dart_ActivationFrame frame;
    res = Dart_GetActivationFrame(trace, i, &frame);
    ASSERT_NOT_ERROR(res);
    Dart_Handle func_name;
    Dart_Handle func;
    Dart_CodeLocation location;
    res = Dart_ActivationFrameGetLocation(frame, &func_name, &func, &location);
    ASSERT_NOT_ERROR(res);
    ASSERT(Dart_IsString(func_name));
    msg->Printf("%s{\"functionName\":", (i > 0) ? "," : "");
    FormatEncodedString(msg, func_name);
    if (!Dart_IsNull(location.script_url)) {
      ASSERT(Dart_IsString(location.script_url));
      msg->Printf(",\"location\": { \"url\":");
      FormatEncodedString(msg, location.script_url);
      msg->Printf(",\"libraryId\":%d,", location.library_id);
      msg->Printf("\"tokenOffset\":%d}", location.token_pos);
    }
    ASSERT_NOT_ERROR(func);
    Dart_Handle origin = Dart_GetFunctionOrigin(func);
    ASSERT_NOT_ERROR(origin);
    if (Dart_IsInteger(origin)) {
      int64_t class_id = GetIntValue(origin);
      msg->Printf(",\"classId\":%" Pd64 "", class_id);
    }
    Dart_Handle locals = Dart_GetLocalVariables(frame);
    ASSERT_NOT_ERROR(locals);
    msg->Printf(",\"locals\":");
    FormatNamedValueList(msg, locals);
    msg->Printf("}");
  }
  msg->Printf("]");
}


typedef bool (*CommandHandler)(DbgMessage* msg);

struct JSONDebuggerCommand {
  const char* cmd_string;
  CommandHandler handler_function;
};


static JSONDebuggerCommand debugger_commands[] = {
  { "resume", DbgMessage::HandleResumeCmd },
  { "stepInto", DbgMessage::HandleStepIntoCmd },
  { "stepOut", DbgMessage::HandleStepOutCmd },
  { "stepOver", DbgMessage::HandleStepOverCmd },
  { "getLibraries", DbgMessage::HandleGetLibrariesCmd },
  { "getClassProperties", DbgMessage::HandleGetClassPropsCmd },
  { "getLibraryProperties", DbgMessage::HandleGetLibPropsCmd },
  { "setLibraryProperties", DbgMessage::HandleSetLibPropsCmd },
  { "evaluateExpr", DbgMessage::HandleEvaluateExprCmd },
  { "getObjectProperties", DbgMessage::HandleGetObjPropsCmd },
  { "getListElements", DbgMessage::HandleGetListCmd },
  { "getGlobalVariables", DbgMessage::HandleGetGlobalsCmd },
  { "getScriptURLs", DbgMessage::HandleGetScriptURLsCmd },
  { "getScriptSource", DbgMessage::HandleGetSourceCmd },
  { "getLineNumberTable", DbgMessage::HandleGetLineNumbersCmd },
  { "getStackTrace", DbgMessage::HandleGetStackTraceCmd },
  { "setBreakpoint", DbgMessage::HandleSetBpCmd },
  { "setPauseOnException", DbgMessage::HandlePauseOnExcCmd },
  { "removeBreakpoint", DbgMessage::HandleRemBpCmd },
  { NULL, NULL }
};


bool DbgMessage::HandleMessage() {
  // Dispatch to the appropriate handler for the command.
  int max_index = (sizeof(debugger_commands) / sizeof(JSONDebuggerCommand));
  ASSERT(cmd_idx_ < max_index);
  return (*debugger_commands[cmd_idx_].handler_function)(this);
}


void DbgMessage::SendReply(dart::TextBuffer* reply) {
  DebuggerConnectionHandler::SendMsg(debug_fd(), reply);
}


void DbgMessage::SendErrorReply(int msg_id, const char* err_msg) {
  DebuggerConnectionHandler::SendError(debug_fd(), msg_id, err_msg);
}


bool DbgMessage::HandleResumeCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  dart::TextBuffer msg(64);
  msg.Printf("{ \"id\": %d }", msg_id);
  in_msg->SendReply(&msg);
  return true;
}


bool DbgMessage::HandleStepIntoCmd(DbgMessage* in_msg) {
  Dart_Handle res = Dart_SetStepInto();
  ASSERT_NOT_ERROR(res);
  return HandleResumeCmd(in_msg);
}


bool DbgMessage::HandleStepOutCmd(DbgMessage* in_msg) {
  Dart_Handle res = Dart_SetStepOut();
  ASSERT_NOT_ERROR(res);
  return HandleResumeCmd(in_msg);
}


bool DbgMessage::HandleStepOverCmd(DbgMessage* in_msg) {
  Dart_Handle res = Dart_SetStepOver();
  ASSERT_NOT_ERROR(res);
  return HandleResumeCmd(in_msg);
}


bool DbgMessage::HandleGetLibrariesCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  dart::TextBuffer msg(64);
  msg.Printf("{ \"id\": %d, \"result\": { \"libraries\": [", msg_id);
  Dart_Handle lib_ids = Dart_GetLibraryIds();
  ASSERT_NOT_ERROR(lib_ids);
  intptr_t num_libs;
  Dart_Handle res = Dart_ListLength(lib_ids, &num_libs);
  ASSERT_NOT_ERROR(res);
  for (intptr_t i = 0; i < num_libs; i++) {
    Dart_Handle lib_id_handle = Dart_ListGetAt(lib_ids, i);
    ASSERT(Dart_IsInteger(lib_id_handle));
    int64_t lib_id = GetIntValue(lib_id_handle);
    ASSERT((lib_id >= kIntptrMin) && (lib_id <= kIntptrMax));
    Dart_Handle lib_url = Dart_GetLibraryURL(static_cast<intptr_t>(lib_id));
    ASSERT_NOT_ERROR(lib_url);
    ASSERT(Dart_IsString(lib_url));
    msg.Printf("%s{\"id\":%" Pd64 ",\"url\":", (i == 0) ? "" : ", ", lib_id);
    FormatEncodedString(&msg, lib_url);
    msg.Printf("}");
  }
  msg.Printf("]}}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleGetClassPropsCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  intptr_t cls_id = msg_parser.GetIntParam("classId");
  dart::TextBuffer msg(64);
  msg.Printf("{\"id\":%d, \"result\":", msg_id);
  const char* err = FormatClassProps(&msg, cls_id);
  if (err != NULL) {
    in_msg->SendErrorReply(msg_id, err);
    return false;
  }
  msg.Printf("}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleGetLibPropsCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
  dart::TextBuffer msg(64);
  msg.Printf("{\"id\":%d, \"result\":", msg_id);
  const char* err = FormatLibraryProps(&msg, lib_id);
  if (err != NULL) {
    in_msg->SendErrorReply(msg_id, err);
    return false;
  }
  msg.Printf("}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleSetLibPropsCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
  const char* enable_request = msg_parser.GetStringParam("debuggingEnabled");
  bool enable;
  if (strcmp(enable_request, "true") == 0) {
    enable = true;
  } else if (strcmp(enable_request, "false") == 0) {
    enable = false;
  } else {
    in_msg->SendErrorReply(msg_id, "illegal argument for 'debuggingEnabled'");
    return false;
  }
  Dart_Handle res = Dart_SetLibraryDebuggable(lib_id, enable);
  if (Dart_IsError(res)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(res));
    return false;
  }
  bool enabled = false;
  res = Dart_GetLibraryDebuggable(lib_id, &enabled);
  if (Dart_IsError(res)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(res));
    return false;
  }
  dart::TextBuffer msg(64);
  msg.Printf("{\"id\":%d, \"result\": {\"debuggingEnabled\": \"%s\"}}",
             msg_id,
             enabled ? "true" : "false");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleEvaluateExprCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  Dart_Handle target = Dart_Null();
  Dart_ActivationFrame frame = NULL;

  if (msg_parser.HasParam("libraryId")) {
    intptr_t lib_id = msg_parser.GetIntParam("libraryId");
    target = Dart_GetLibraryFromId(lib_id);
  } else if (msg_parser.HasParam("classId")) {
    intptr_t cls_id = msg_parser.GetIntParam("classId");
    target = Dart_GetClassFromId(cls_id);
  } else if (msg_parser.HasParam("objectId")) {
    intptr_t obj_id = msg_parser.GetIntParam("objectId");
    target = Dart_GetCachedObject(obj_id);
  } else if (msg_parser.HasParam("frameId")) {
    intptr_t frame_index = msg_parser.GetIntParam("frameId");
    Dart_Handle res;
    Dart_StackTrace stack_trace;
    res = Dart_GetStackTrace(&stack_trace);
    ASSERT_NOT_ERROR(res);
    intptr_t trace_length = 0;
    res = Dart_StackTraceLength(stack_trace, &trace_length);
    ASSERT_NOT_ERROR(res);
    if (frame_index >= trace_length) {
      in_msg->SendErrorReply(msg_id, "illegal frame index");
      return false;
    }
    res = Dart_GetActivationFrame(stack_trace, frame_index, &frame);
    ASSERT_NOT_ERROR(res);
  } else {
    in_msg->SendErrorReply(msg_id, "illegal evaluation target");
    return false;
  }

  char* expr_chars = msg_parser.GetStringParam("expression");
  Dart_Handle expr = Dart_NewStringFromCString(expr_chars);
  if (Dart_IsError(expr)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(expr));
    return false;
  }

  Dart_Handle eval_result = Dart_Null();
  if (frame != NULL) {
    eval_result = Dart_ActivationFrameEvaluate(frame, expr);
  } else {
    if (Dart_IsError(target)) {
      in_msg->SendErrorReply(msg_id, Dart_GetError(target));
      return false;
    }
    eval_result = Dart_EvaluateExpr(target, expr);
  }
  if (Dart_IsError(eval_result)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(eval_result));
    return false;
  }

  dart::TextBuffer msg(64);
  msg.Printf("{\"id\":%d, \"result\":", msg_id);
  FormatRemoteObj(&msg, eval_result);
  msg.Printf("}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleGetObjPropsCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  intptr_t obj_id = msg_parser.GetIntParam("objectId");
  Dart_Handle obj = Dart_GetCachedObject(obj_id);
  if (Dart_IsError(obj)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(obj));
    return false;
  }
  dart::TextBuffer msg(64);
  msg.Printf("{\"id\":%d, \"result\":", msg_id);
  const char* err = FormatObjProps(&msg, obj);
  if (err != NULL) {
    in_msg->SendErrorReply(msg_id, err);
    return false;
  }
  msg.Printf("}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleGetListCmd(DbgMessage* in_msg) {
  const intptr_t kDefaultSliceLength = 100;
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  intptr_t obj_id = msg_parser.GetIntParam("objectId");
  Dart_Handle list = Dart_GetCachedObject(obj_id);
  if (Dart_IsError(list)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(list));
    return false;
  }
  if (!Dart_IsList(list)) {
    in_msg->SendErrorReply(msg_id, "object is not a list");
    return false;
  }
  intptr_t list_length = 0;
  Dart_Handle res = Dart_ListLength(list, &list_length);
  if (Dart_IsError(res)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(res));
    return false;
  }

  intptr_t index = msg_parser.GetIntParam("index");
  if (index < 0) {
    index = 0;
  } else if (index > list_length) {
    index = list_length;
  }

  // If no slice length is given, get only one element. If slice length
  // is given as 0, get entire list.
  intptr_t slice_length = msg_parser.GetOptIntParam("length", 1);
  if (slice_length == 0) {
    slice_length = list_length - index;
  }
  if ((index + slice_length) > list_length) {
    slice_length = list_length - index;
  }
  ASSERT(slice_length >= 0);
  if (slice_length > kDefaultSliceLength) {
    slice_length = kDefaultSliceLength;
  }
  dart::TextBuffer msg(64);
  msg.Printf("{\"id\":%d, \"result\":", msg_id);
  if (slice_length == 1) {
    Dart_Handle value = Dart_ListGetAt(list, index);
    FormatRemoteObj(&msg, value);
  } else {
    FormatListSlice(&msg, list, list_length, index, slice_length);
  }
  msg.Printf("}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleGetGlobalsCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
  dart::TextBuffer msg(64);
  msg.Printf("{\"id\":%d, \"result\": { \"globals\":", msg_id);
  Dart_Handle globals = Dart_GetGlobalVariables(lib_id);
  ASSERT_NOT_ERROR(globals);
  FormatNamedValueList(&msg, globals);
  msg.Printf("}}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleGetScriptURLsCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  dart::TextBuffer msg(64);
  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
  Dart_Handle lib_url = Dart_GetLibraryURL(lib_id);
  ASSERT_NOT_ERROR(lib_url);
  Dart_Handle urls = Dart_GetScriptURLs(lib_url);
  if (Dart_IsError(urls)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(urls));
    return false;
  }
  ASSERT(Dart_IsList(urls));
  intptr_t num_urls = 0;
  Dart_ListLength(urls, &num_urls);
  msg.Printf("{ \"id\": %d, ", msg_id);
  msg.Printf("\"result\": { \"urls\": [");
  for (int i = 0; i < num_urls; i++) {
    Dart_Handle script_url = Dart_ListGetAt(urls, i);
    if (i > 0) {
      msg.Printf(",");
    }
    FormatEncodedString(&msg, script_url);
  }
  msg.Printf("]}}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleGetSourceCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  dart::TextBuffer msg(64);
  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
  char* url_chars = msg_parser.GetStringParam("url");
  ASSERT(url_chars != NULL);
  Dart_Handle url = DartUtils::NewString(url_chars);
  ASSERT_NOT_ERROR(url);
  free(url_chars);
  url_chars = NULL;
  Dart_Handle source = Dart_ScriptGetSource(lib_id, url);
  if (Dart_IsError(source)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(source));
    return false;
  }
  msg.Printf("{ \"id\": %d, ", msg_id);
  msg.Printf("\"result\": { \"text\": ");
  FormatEncodedString(&msg, source);
  msg.Printf("}}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleGetLineNumbersCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  dart::TextBuffer msg(64);
  intptr_t lib_id = msg_parser.GetIntParam("libraryId");
  char* url_chars = msg_parser.GetStringParam("url");
  ASSERT(url_chars != NULL);
  Dart_Handle url = DartUtils::NewString(url_chars);
  ASSERT_NOT_ERROR(url);
  free(url_chars);
  url_chars = NULL;
  Dart_Handle info = Dart_ScriptGetTokenInfo(lib_id, url);
  if (Dart_IsError(info)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(info));
    return false;
  }
  ASSERT(Dart_IsList(info));
  intptr_t info_len = 0;
  Dart_Handle res = Dart_ListLength(info, &info_len);
  ASSERT_NOT_ERROR(res);
  msg.Printf("{ \"id\": %d, ", msg_id);
  msg.Printf("\"result\": { \"lines\": [");
  Dart_Handle elem;
  intptr_t num_elems = 0;
  for (intptr_t i = 0; i < info_len; i++) {
    elem = Dart_ListGetAt(info, i);
    if (Dart_IsNull(elem)) {
      msg.Printf((i == 0) ? "[" : "], [");
      num_elems = 0;
    } else {
      ASSERT(Dart_IsInteger(elem));
      int64_t value = GetIntValue(elem);
      if (num_elems == 0) {
        msg.Printf("%" Pd64 "", value);
      } else {
        msg.Printf(",%" Pd64 "", value);
      }
      num_elems++;
    }
  }
  msg.Printf("]]}}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleGetStackTraceCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  Dart_StackTrace trace;
  Dart_Handle res = Dart_GetStackTrace(&trace);
  ASSERT_NOT_ERROR(res);
  dart::TextBuffer msg(128);
  msg.Printf("{ \"id\": %d, \"result\": {", msg_id);
  FormatCallFrames(&msg, trace);
  msg.Printf("}}");
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleSetBpCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  char* url_chars = msg_parser.GetStringParam("url");
  ASSERT(url_chars != NULL);
  Dart_Handle url = DartUtils::NewString(url_chars);
  ASSERT_NOT_ERROR(url);
  free(url_chars);
  url_chars = NULL;
  intptr_t line_number = msg_parser.GetIntParam("line");
  Dart_Handle bp_id = Dart_SetBreakpoint(url, line_number);
  if (Dart_IsError(bp_id)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(bp_id));
    return false;
  }
  ASSERT(Dart_IsInteger(bp_id));
  uint64_t bp_id_value;
  Dart_Handle res = Dart_IntegerToUint64(bp_id, &bp_id_value);
  ASSERT_NOT_ERROR(res);
  dart::TextBuffer msg(64);
  msg.Printf("{ \"id\": %d, \"result\": { \"breakpointId\": %" Pu64 " }}",
             msg_id, bp_id_value);
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandlePauseOnExcCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  char* exc_chars = msg_parser.GetStringParam("exceptions");
  Dart_ExceptionPauseInfo info = kNoPauseOnExceptions;
  if (strcmp(exc_chars, "none") == 0) {
    info = kNoPauseOnExceptions;
  } else if (strcmp(exc_chars, "all") == 0) {
    info = kPauseOnAllExceptions;
  } else if (strcmp(exc_chars, "unhandled") == 0) {
    info = kPauseOnUnhandledExceptions;
  } else {
    in_msg->SendErrorReply(msg_id, "illegal value for parameter 'exceptions'");
    return false;
  }
  Dart_Handle res = Dart_SetExceptionPauseInfo(info);
  ASSERT_NOT_ERROR(res);
  dart::TextBuffer msg(32);
  msg.Printf("{ \"id\": %d }", msg_id);
  in_msg->SendReply(&msg);
  return false;
}


bool DbgMessage::HandleRemBpCmd(DbgMessage* in_msg) {
  ASSERT(in_msg != NULL);
  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
  int msg_id = msg_parser.MessageId();
  int bpt_id = msg_parser.GetIntParam("breakpointId");
  Dart_Handle res = Dart_RemoveBreakpoint(bpt_id);
  if (Dart_IsError(res)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(res));
    return false;
  }
  dart::TextBuffer msg(32);
  msg.Printf("{ \"id\": %d }", msg_id);
  in_msg->SendReply(&msg);
  return false;
}


void DbgMsgQueue::AddMessage(int32_t cmd_idx,
                             const char* start,
                             const char* end,
                             intptr_t debug_fd) {
  if ((end > start) && ((end - start) < kMaxInt32)) {
    MonitorLocker ml(&msg_queue_lock_);
    DbgMessage* msg = new DbgMessage(cmd_idx, start, end, debug_fd);
    if (msglist_head_ == NULL) {
      ASSERT(msglist_tail_ == NULL);
      msglist_head_ = msg;
      msglist_tail_ = msg;
      ml.Notify();
    } else {
      ASSERT(msglist_tail_ != NULL);
      msglist_tail_->set_next(msg);
      msglist_tail_ = msg;
    }
  }
}


void DbgMsgQueue::Notify() {
  MonitorLocker ml(&msg_queue_lock_);
  ml.Notify();
}


bool DbgMsgQueue::HandlePendingMessages() {
  // Handle all available debug messages, up to a resume request.
  bool resume_requested = false;
  while (msglist_head_ != NULL && !resume_requested) {
    ASSERT(msglist_tail_ != NULL);
    DbgMessage* msg = msglist_head_;
    msglist_head_ = msglist_head_->next();
    if (msglist_head_ == NULL) {
      msglist_tail_ = NULL;
    }
    resume_requested = msg->HandleMessage();
    delete msg;
  }
  return resume_requested;
}


void DbgMsgQueue::MessageLoop() {
  MonitorLocker ml(&msg_queue_lock_);
  is_running_ = false;

  // Request notification on isolate messages.  This allows us to
  // respond to vm service messages while at breakpoint.
  Dart_SetMessageNotifyCallback(DbgMsgQueueList::NotifyIsolate);

  while (true) {
    // Handle all available vm service messages, up to a resume
    // request.
    bool resume = false;
    while (!resume && Dart_HasServiceMessages()) {
      // Release the message queue lock before handling service
      // messages.  This allows notifications to come in while we are
      // processing long requests and avoids deadlock with the PortMap
      // lock in the vm.
      msg_queue_lock_.Exit();
      resume = Dart_HandleServiceMessages();
      msg_queue_lock_.Enter();
    }
    if (resume) {
      break;
    }

    // Handle all available debug messages, up to a resume request.
    if (HandlePendingMessages()) {
      break;
    }

    // Wait for more debug or vm service messages.
    Monitor::WaitResult res = ml.Wait();
    ASSERT(res == Monitor::kNotified);
  }
  Dart_SetMessageNotifyCallback(NULL);
  is_interrupted_ = false;
  is_running_ = true;
}


void DbgMsgQueue::InterruptIsolate() {
  Dart_Isolate isolate = Dart_GetIsolate(isolate_id_);
  MonitorLocker ml(&msg_queue_lock_);
  if (is_running_ && !is_interrupted_) {
    is_interrupted_ = true;
    Dart_InterruptIsolate(isolate);
  }
}


void DbgMsgQueue::QueueOutputMsg(dart::TextBuffer* msg) {
  queued_output_messages_.Printf("%s", msg->buf());
}


void DbgMsgQueue::SendQueuedMsgs() {
  if (queued_output_messages_.length() > 0) {
    DebuggerConnectionHandler::BroadcastMsg(&queued_output_messages_);
    queued_output_messages_.Clear();
  }
}


void DbgMsgQueue::SendBreakpointEvent(intptr_t bp_id,
                                      const Dart_CodeLocation& location) {
  dart::TextBuffer msg(128);
  msg.Printf("{ \"event\": \"paused\", \"params\": { ");
  msg.Printf("\"reason\": \"breakpoint\", ");
  msg.Printf("\"isolateId\": %" Pd64 "", isolate_id_);
  if (bp_id != ILLEGAL_BREAKPOINT_ID) {
    msg.Printf(",\"breakpointId\": %" Pd "", bp_id);
  }
  if (!Dart_IsNull(location.script_url)) {
    ASSERT(Dart_IsString(location.script_url));
    msg.Printf(",\"location\": { \"url\":");
    FormatEncodedString(&msg, location.script_url);
    msg.Printf(",\"libraryId\":%d,", location.library_id);
    msg.Printf("\"tokenOffset\":%d}", location.token_pos);
  }
  msg.Printf("}}");
  DebuggerConnectionHandler::BroadcastMsg(&msg);
}


// TODO(hausner): Remove stack trace parameter once we remove the stack
// trace from the paused event in the wire protocol.
void DbgMsgQueue::SendExceptionEvent(Dart_Handle exception,
                                     Dart_StackTrace stack_trace) {
  intptr_t exception_id = Dart_CacheObject(exception);
  ASSERT(exception_id >= 0);
  dart::TextBuffer msg(128);
  msg.Printf("{ \"event\": \"paused\", \"params\": {");
  msg.Printf("\"reason\": \"exception\", ");
  msg.Printf("\"isolateId\": %" Pd64 ", ", isolate_id_);
  msg.Printf("\"exception\":");
  FormatRemoteObj(&msg, exception);
  FormatLocationFromTrace(&msg, stack_trace, ", ");
  msg.Printf("}}");
  DebuggerConnectionHandler::BroadcastMsg(&msg);
}


// TODO(hausner): Remove stack trace parameter once we remove the stack
// trace from the interrupted event in the wire protocol.
void DbgMsgQueue::SendIsolateEvent(Dart_IsolateId isolate_id,
                                   Dart_IsolateEvent kind) {
  dart::TextBuffer msg(128);
  if (kind == kInterrupted) {
    Dart_StackTrace trace;
    Dart_Handle res = Dart_GetStackTrace(&trace);
    ASSERT_NOT_ERROR(res);
    msg.Printf("{ \"event\": \"paused\", \"params\": { ");
    msg.Printf("\"reason\": \"interrupted\", ");
    msg.Printf("\"isolateId\": %" Pd64 "", isolate_id);
    FormatLocationFromTrace(&msg, trace, ", ");
    msg.Printf("}}");
  } else {
    msg.Printf("{ \"event\": \"isolate\", \"params\": { ");
    if (kind == kCreated) {
      msg.Printf("\"reason\": \"created\", ");
    } else {
      ASSERT(kind == kShutdown);
      msg.Printf("\"reason\": \"shutdown\", ");
    }
    msg.Printf("\"id\": %" Pd64 " ", isolate_id);
    msg.Printf("}}");
  }
  DebuggerConnectionHandler::BroadcastMsg(&msg);
}


DbgMsgQueue* DbgMsgQueueList::list_ = NULL;
Mutex* DbgMsgQueueList::msg_queue_list_lock_ = new Mutex();


void DbgMsgQueueList::Initialize() {
  // Setup handlers for isolate events, breakpoints, exceptions and
  // delayed breakpoints.
  Dart_SetIsolateEventHandler(IsolateEventHandler);
  Dart_SetPausedEventHandler(PausedEventHandler);
  Dart_SetBreakpointResolvedHandler(BptResolvedHandler);
  Dart_SetExceptionThrownHandler(ExceptionThrownHandler);
}


int32_t DbgMsgQueueList::LookupIsolateCommand(const char* buf,
                                              int32_t buflen) {
  // Check if we have a isolate specific debugger command.
  int32_t i = 0;
  while (debugger_commands[i].cmd_string != NULL) {
    if (strncmp(buf, debugger_commands[i].cmd_string, buflen) == 0) {
      return i;
    }
    i++;
  }
  return kInvalidCommand;
}


bool DbgMsgQueueList::AddIsolateMessage(Dart_IsolateId isolate_id,
                                        int32_t cmd_idx,
                                        const char* start,
                                        const char* end,
                                        intptr_t debug_fd) {
  MutexLocker ml(msg_queue_list_lock_);
  DbgMsgQueue* queue = DbgMsgQueueList::GetIsolateMsgQueueLocked(isolate_id);
  if (queue != NULL) {
    queue->AddMessage(cmd_idx, start, end, debug_fd);
    return true;
  }
  return false;
}


void DbgMsgQueueList::NotifyIsolate(Dart_Isolate isolate) {
  MutexLocker ml(msg_queue_list_lock_);
  Dart_IsolateId isolate_id = Dart_GetIsolateId(isolate);
  DbgMsgQueue* queue = DbgMsgQueueList::GetIsolateMsgQueueLocked(isolate_id);
  if (queue != NULL) {
    queue->Notify();
  }
}


bool DbgMsgQueueList::InterruptIsolate(Dart_IsolateId isolate_id) {
  MutexLocker ml(msg_queue_list_lock_);
  DbgMsgQueue* queue = DbgMsgQueueList::GetIsolateMsgQueueLocked(isolate_id);
  if (queue != NULL) {
    queue->InterruptIsolate();
    return true;
  }
  return false;
}


DbgMsgQueue* DbgMsgQueueList::AddIsolateMsgQueue(Dart_IsolateId isolate_id) {
  MutexLocker ml(msg_queue_list_lock_);

  DbgMsgQueue* queue = new DbgMsgQueue(isolate_id, list_);
  ASSERT(queue != NULL);
  list_ = queue;
  return queue;
}


DbgMsgQueue* DbgMsgQueueList::GetIsolateMsgQueue(Dart_IsolateId isolate_id) {
  MutexLocker ml(msg_queue_list_lock_);
  ASSERT(Dart_GetIsolate(isolate_id) == Dart_CurrentIsolate());
  return GetIsolateMsgQueueLocked(isolate_id);
}


DbgMsgQueue* DbgMsgQueueList::GetIsolateMsgQueueLocked(Dart_IsolateId id) {
  if (list_ == NULL) {
    return NULL;  // No items in the list.
  }

  // Find message queue corresponding to isolate id.
  DbgMsgQueue* iterator = list_;
  while (iterator != NULL && iterator->isolate_id() != id) {
    iterator = iterator->next();
  }
  return iterator;
}


void DbgMsgQueueList::RemoveIsolateMsgQueue(Dart_IsolateId isolate_id) {
  MutexLocker ml(msg_queue_list_lock_);
  if (list_ == NULL) {
    return;  // No items in the list.
  }
  DbgMsgQueue* queue = list_;
  if (queue->isolate_id() == isolate_id) {
    list_ = queue->next();  // Remove from list.
    delete queue;  // Delete the message queue.
    return;
  } else {
    DbgMsgQueue* iterator = queue;
    queue = queue->next();
    while (queue != NULL) {
      if (queue->isolate_id() == isolate_id) {
        iterator->set_next(queue->next());  // Remove from list.
        delete queue;  // Delete the message queue.
        return;
      }
      iterator = queue;
      queue = queue->next();
    }
  }
  UNREACHABLE();
}


void DbgMsgQueueList::ListIsolateIds(dart::TextBuffer* msg) {
  MutexLocker ml(msg_queue_list_lock_);
  if (list_ == NULL) {
    return;  // No items in the list.
  }
  DbgMsgQueue* queue = list_;
  msg->Printf("%" Pd64 "", queue->isolate_id());
  queue = queue->next();
  while (queue != NULL) {
    msg->Printf(",%" Pd64 "", queue->isolate_id());
    queue = queue->next();
  }
}


void DbgMsgQueueList::BptResolvedHandler(Dart_IsolateId isolate_id,
                                         intptr_t bp_id,
                                         const Dart_CodeLocation& location) {
  Dart_EnterScope();
  dart::TextBuffer msg(128);
  msg.Printf("{ \"event\": \"breakpointResolved\", \"params\": {");
  msg.Printf("\"breakpointId\": %" Pd "", bp_id);

  msg.Printf(", \"isolateId\":%" Pd64 "", isolate_id);
  ASSERT(!Dart_IsNull(location.script_url));
  ASSERT(Dart_IsString(location.script_url));
  msg.Printf(", \"location\":{\"url\":");
  FormatEncodedString(&msg, location.script_url);
  msg.Printf(",\"libraryId\":%d", location.library_id);
  msg.Printf(",\"tokenOffset\":%d}}}", location.token_pos);

  DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id);
  ASSERT(msg_queue != NULL);
  msg_queue->QueueOutputMsg(&msg);
  Dart_ExitScope();
}


void DbgMsgQueueList::PausedEventHandler(Dart_IsolateId isolate_id,
                                         intptr_t bp_id,
                                         const Dart_CodeLocation& loc) {
  DebuggerConnectionHandler::WaitForConnection();
  Dart_EnterScope();
  DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id);
  ASSERT(msg_queue != NULL);
  msg_queue->SendQueuedMsgs();
  msg_queue->SendBreakpointEvent(bp_id, loc);
  msg_queue->MessageLoop();
  Dart_ExitScope();
}


void DbgMsgQueueList::ExceptionThrownHandler(Dart_IsolateId isolate_id,
                                             Dart_Handle exception,
                                             Dart_StackTrace stack_trace) {
  DebuggerConnectionHandler::WaitForConnection();
  Dart_EnterScope();
  DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id);
  ASSERT(msg_queue != NULL);
  msg_queue->SendQueuedMsgs();
  msg_queue->SendExceptionEvent(exception, stack_trace);
  msg_queue->MessageLoop();
  Dart_ExitScope();
}


void DbgMsgQueueList::IsolateEventHandler(Dart_IsolateId isolate_id,
                                          Dart_IsolateEvent kind) {
  DebuggerConnectionHandler::WaitForConnection();
  Dart_EnterScope();
  if (kind == kCreated) {
    DbgMsgQueue* msg_queue = AddIsolateMsgQueue(isolate_id);
    msg_queue->SendIsolateEvent(isolate_id, kind);
  } else {
    DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id);
    ASSERT(msg_queue != NULL);
    msg_queue->SendQueuedMsgs();
    msg_queue->SendIsolateEvent(isolate_id, kind);
    if (kind == kInterrupted) {
      msg_queue->MessageLoop();
    } else {
      ASSERT(kind == kShutdown);
      RemoveIsolateMsgQueue(isolate_id);
    }
  }
  Dart_ExitScope();
}

}  // namespace bin
}  // namespace dart
