// 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/thread.h"
#include "bin/utils.h"

#include "platform/globals.h"
#include "platform/json.h"
#include "platform/thread.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);
}


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 int 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);
  // TODO(hausner): Range check.
  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* codepoints =
      reinterpret_cast<uint16_t*>(malloc(num_chars * sizeof(uint16_t)));
  ASSERT(codepoints != NULL);
  intptr_t actual_len = num_chars;
  res = Dart_StringToUTF16(str, codepoints, &actual_len);
  ASSERT_NOT_ERROR(res);
  ASSERT(num_chars == actual_len);
  for (int i = 0; i < num_chars; i++) {
    buf->AddEscapedChar(codepoints[i]);
  }
  if (str_len > max_chars) {
    buf->Printf("...");
  }
  free(codepoints);
}


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* codepoints =
      reinterpret_cast<uint16_t*>(malloc(str_len * sizeof(uint16_t)));
  ASSERT(codepoints != NULL);
  intptr_t actual_len = str_len;
  res = Dart_StringToUTF16(str, codepoints, &actual_len);
  ASSERT_NOT_ERROR(res);
  ASSERT(str_len == actual_len);
  for (int i = 0; i < str_len; i++) {
    buf->AddEscapedChar(codepoints[i]);
  }
  free(codepoints);
}


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);


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);
    if (buf->length() > max_buffer_length) {
      buf->Printf(", ...");
      break;
    }
  }
  buf->Printf("]");
}


static void FormatTextualValue(dart::TextBuffer* buf,
                               Dart_Handle object,
                               intptr_t max_chars) {
  if (Dart_IsList(object)) {
    FormatTextualListValue(buf, object, max_chars);
  } else if (Dart_IsNull(object)) {
    buf->Printf("null");
  } else if (Dart_IsString(object)) {
    buf->Printf("\\\"");
    FormatEncodedCharsTrunc(buf, object, max_chars);
    buf->Printf("\\\"");
  } else {
    Dart_Handle text = Dart_ToString(object);
    if (Dart_IsNull(text)) {
      buf->Printf("null");
    } else if (Dart_IsError(text)) {
      buf->Printf("#ERROR");
    } else {
      FormatEncodedCharsTrunc(buf, text, max_chars);
    }
  }
}


static void FormatValue(dart::TextBuffer* buf, Dart_Handle object) {
  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 {
    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);
    }
  }
  buf->Printf("\"text\":\"");
  const intptr_t max_chars = 250;
  FormatTextualValue(buf, object, max_chars);
  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 (int 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\":%d,",
                (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);
  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_CodeLocation location;
    res = Dart_ActivationFrameGetLocation(frame, &func_name, NULL, &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);
    }
    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 (int i = 0; i < num_libs; i++) {
    Dart_Handle lib_id_handle = Dart_ListGetAt(lib_ids, i);
    ASSERT(Dart_IsInteger(lib_id_handle));
    int lib_id = GetIntValue(lib_id_handle);
    Dart_Handle lib_url = Dart_GetLibraryURL(lib_id);
    ASSERT_NOT_ERROR(lib_url);
    ASSERT(Dart_IsString(lib_url));
    msg.Printf("%s{\"id\":%d,\"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;

  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 {
    in_msg->SendErrorReply(msg_id, "illegal evaluation target");
    return false;
  }

  if (Dart_IsError(target)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(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 value = Dart_EvaluateExpr(target, expr);
  if (Dart_IsError(value)) {
    in_msg->SendErrorReply(msg_id, Dart_GetError(value));
    return false;
  }

  dart::TextBuffer msg(64);
  msg.Printf("{\"id\":%d, \"result\":", msg_id);
  FormatRemoteObj(&msg, value);
  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));
      int value = GetIntValue(elem);
      if (num_elems == 0) {
        msg.Printf("%d", value);
      } else {
        msg.Printf(",%d", 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,
                             int 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::HandleMessages() {
  bool resume_requested = false;
  MonitorLocker ml(&msg_queue_lock_);
  is_running_ = false;
  while (!resume_requested) {
    while (msglist_head_ == NULL) {
      ASSERT(msglist_tail_ == NULL);
      dart::Monitor::WaitResult res = ml.Wait();  // Wait for debugger commands.
      ASSERT(res == dart::Monitor::kNotified);
    }
    while (msglist_head_ != NULL && !resume_requested) {
      ASSERT(msglist_tail_ != NULL);
      DbgMessage* msg = msglist_head_;
      msglist_head_ = msglist_head_->next();
      resume_requested = msg->HandleMessage();
      delete msg;
    }
    if (msglist_head_ == NULL) {
      msglist_tail_ = 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(const Dart_CodeLocation& location) {
  dart::TextBuffer msg(128);
  msg.Printf("{ \"event\": \"paused\", \"params\": { ");
  msg.Printf("\"reason\": \"breakpoint\", ");
  msg.Printf("\"isolateId\": %" Pd64 "", isolate_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;
dart::Mutex* DbgMsgQueueList::msg_queue_list_lock_ = new dart::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,
                                        int 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;
}


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,
                                         const Dart_CodeLocation& loc) {
  DebuggerConnectionHandler::WaitForConnection();
  Dart_EnterScope();
  DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id);
  ASSERT(msg_queue != NULL);
  msg_queue->SendQueuedMsgs();
  msg_queue->SendBreakpointEvent(loc);
  msg_queue->HandleMessages();
  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->HandleMessages();
  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->HandleMessages();
    } else {
      ASSERT(kind == kShutdown);
      RemoveIsolateMsgQueue(isolate_id);
    }
  }
  Dart_ExitScope();
}

}  // namespace bin
}  // namespace dart
