// 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 "include/dart_debugger_api.h"

#include "vm/dart_api_impl.h"
#include "vm/dart_api_state.h"
#include "vm/debugger.h"
#include "vm/isolate.h"
#include "vm/object_store.h"
#include "vm/symbols.h"

namespace dart {

#define UNWRAP_AND_CHECK_PARAM(type, var, param)                               \
  type& var = type::Handle();                                                  \
  do {                                                                         \
    const Object& tmp = Object::Handle(Api::UnwrapHandle(param));              \
    if (tmp.IsNull()) {                                                        \
      return Api::NewError("%s expects argument '%s' to be non-null.",         \
                           CURRENT_FUNC, #param);                              \
    } else if (tmp.IsApiError()) {                                             \
      return param;                                                            \
    } else if (!tmp.Is##type()) {                                              \
      return Api::NewError("%s expects argument '%s' to be of type %s.",       \
                           CURRENT_FUNC, #param, #type);                       \
    }                                                                          \
    var ^= tmp.raw();                                                          \
  } while (0)


#define CHECK_AND_CAST(type, var, param)                                       \
  type* var = NULL;                                                            \
  do {                                                                         \
    if (param == NULL) {                                                       \
      return Api::NewError("%s expects argument '%s' to be non-null.",         \
                           CURRENT_FUNC, #param);                              \
    }                                                                          \
    var = reinterpret_cast<type*>(param);                                      \
  } while (0)


#define CHECK_NOT_NULL(param)                                                  \
  if (param == NULL) {                                                         \
    return Api::NewError("%s expects argument '%s' to be non-null.",           \
                         CURRENT_FUNC, #param);                                \
  }


DART_EXPORT intptr_t Dart_CacheObject(Dart_Handle object_in) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  const Object& obj = Object::Handle(Api::UnwrapHandle(object_in));
  if (obj.IsApiError()) {
    return -1;
  }
  return isolate->debugger()->CacheObject(obj);
}


DART_EXPORT Dart_Handle Dart_GetCachedObject(intptr_t obj_id) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  if (!isolate->debugger()->IsValidObjectId(obj_id)) {
    return Api::NewError("%s: object id %"Pd" is invalid",
                         CURRENT_FUNC, obj_id);
  }
  return Api::NewHandle(isolate, isolate->debugger()->GetCachedObject(obj_id));
}


DART_EXPORT Dart_Handle Dart_StackTraceLength(
                            Dart_StackTrace trace,
                            intptr_t* length) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  CHECK_NOT_NULL(length);
  CHECK_AND_CAST(DebuggerStackTrace, stack_trace, trace);
  *length = stack_trace->Length();
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_GetActivationFrame(
                            Dart_StackTrace trace,
                            int frame_index,
                            Dart_ActivationFrame* frame) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  CHECK_NOT_NULL(frame);
  CHECK_AND_CAST(DebuggerStackTrace, stack_trace, trace);
  if ((frame_index < 0) || (frame_index >= stack_trace->Length())) {
    return Api::NewError("argument 'frame_index' is out of range for %s",
                         CURRENT_FUNC);
  }
  *frame = reinterpret_cast<Dart_ActivationFrame>(
       stack_trace->ActivationFrameAt(frame_index));
  return Api::True(isolate);
}


DART_EXPORT void Dart_SetBreakpointHandler(Dart_BreakpointHandler bp_handler) {
  BreakpointHandler* handler =
      reinterpret_cast<BreakpointHandler*>(bp_handler);
  Debugger::SetBreakpointHandler(handler);
}


static Dart_BreakpointResolvedHandler* bp_resolved_handler = NULL;
static Dart_ExceptionThrownHandler* exc_thrown_handler = NULL;
static Dart_IsolateEventHandler* isolate_event_handler = NULL;


static void DebuggerEventHandler(Debugger::DebuggerEvent* event) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  ASSERT(isolate->debugger() != NULL);
  Dart_IsolateId isolate_id = isolate->debugger()->GetIsolateId();
  if (event->type == Debugger::kBreakpointResolved) {
    if (bp_resolved_handler == NULL) {
      return;
    }
    SourceBreakpoint* bpt = event->breakpoint;
    ASSERT(bpt != NULL);
    Dart_Handle url = Api::NewHandle(isolate, bpt->SourceUrl());
    (*bp_resolved_handler)(isolate_id, bpt->id(), url, bpt->LineNumber());
  } else if (event->type == Debugger::kExceptionThrown) {
    if (exc_thrown_handler == NULL) {
      return;
    }
    Dart_Handle exception = Api::NewHandle(isolate, event->exception->raw());
    Dart_StackTrace trace =
        reinterpret_cast<Dart_StackTrace>(isolate->debugger()->StackTrace());
    (*exc_thrown_handler)(isolate_id, exception, trace);
  } else if (event->type == Debugger::kIsolateCreated) {
    if (isolate_event_handler != NULL) {
      (*isolate_event_handler)(event->isolate_id, kCreated);
    }
  } else if (event->type == Debugger::kIsolateInterrupted) {
    if (isolate_event_handler != NULL) {
      (*isolate_event_handler)(event->isolate_id, kInterrupted);
    }
  } else if (event->type == Debugger::kIsolateShutdown) {
    if (isolate_event_handler != NULL) {
      (*isolate_event_handler)(event->isolate_id, kShutdown);
    }
  } else {
    UNIMPLEMENTED();
  }
}


DART_EXPORT void Dart_SetBreakpointResolvedHandler(
                            Dart_BreakpointResolvedHandler handler) {
  bp_resolved_handler = handler;
  Debugger::SetEventHandler(DebuggerEventHandler);
}


DART_EXPORT void Dart_SetExceptionThrownHandler(
                            Dart_ExceptionThrownHandler handler) {
  exc_thrown_handler = handler;
  Debugger::SetEventHandler(DebuggerEventHandler);
}


DART_EXPORT void Dart_SetIsolateEventHandler(Dart_IsolateEventHandler handler) {
  isolate_event_handler = handler;
  Debugger::SetEventHandler(DebuggerEventHandler);
}


DART_EXPORT Dart_Handle Dart_SetExceptionPauseInfo(
                            Dart_ExceptionPauseInfo pause_info) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  isolate->debugger()->SetExceptionPauseInfo(pause_info);
  return Api::True(isolate);
}


DART_EXPORT Dart_ExceptionPauseInfo Dart_GetExceptionPauseInfo() {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  return isolate->debugger()->GetExceptionPauseInfo();
}


DART_EXPORT Dart_Handle Dart_GetStackTrace(Dart_StackTrace* trace) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  CHECK_NOT_NULL(trace);
  *trace = reinterpret_cast<Dart_StackTrace>(isolate->debugger()->StackTrace());
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_ActivationFrameInfo(
                            Dart_ActivationFrame activation_frame,
                            Dart_Handle* function_name,
                            Dart_Handle* script_url,
                            intptr_t* line_number,
                            intptr_t* library_id) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  CHECK_AND_CAST(ActivationFrame, frame, activation_frame);
  if (function_name != NULL) {
    *function_name = Api::NewHandle(isolate, frame->QualifiedFunctionName());
  }
  if (script_url != NULL) {
    *script_url = Api::NewHandle(isolate, frame->SourceUrl());
  }
  if (line_number != NULL) {
    *line_number = frame->LineNumber();
  }
  if (library_id != NULL) {
    const Library& lib = Library::Handle(frame->Library());
    *library_id = lib.index();
  }
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_GetLocalVariables(
                            Dart_ActivationFrame activation_frame) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  CHECK_AND_CAST(ActivationFrame, frame, activation_frame);
  return Api::NewHandle(isolate, frame->GetLocalVariables());
}


DART_EXPORT Dart_Handle Dart_SetBreakpoint(
                            Dart_Handle script_url_in,
                            intptr_t line_number) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
  Debugger* debugger = isolate->debugger();
  ASSERT(debugger != NULL);
  SourceBreakpoint* bpt =
      debugger->SetBreakpointAtLine(script_url, line_number);
  if (bpt == NULL) {
    return Api::NewError("%s: could not set breakpoint at line %"Pd" in '%s'",
                         CURRENT_FUNC, line_number, script_url.ToCString());
  }
  return Dart_NewInteger(bpt->id());
}


// TODO(hausner): remove this function.
DART_EXPORT Dart_Handle Dart_SetBreakpointAtLine(
                            Dart_Handle script_url_in,
                            Dart_Handle line_number_in,
                            Dart_Breakpoint* breakpoint) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
  UNWRAP_AND_CHECK_PARAM(Integer, line_number, line_number_in);
  CHECK_NOT_NULL(breakpoint);

  if (!line_number.IsSmi()) {
    return Api::NewError("%s: line number out of range", CURRENT_FUNC);
  }
  intptr_t line = line_number.AsInt64Value();

  Dart_Handle state = Api::CheckIsolateState(isolate);
  if (::Dart_IsError(state)) {
    return state;
  }

  Dart_Handle result = Api::True(isolate);
  *breakpoint = NULL;
  Debugger* debugger = isolate->debugger();
  ASSERT(debugger != NULL);
  SourceBreakpoint* bpt =
      debugger->SetBreakpointAtLine(script_url, line);
  if (bpt == NULL) {
    result = Api::NewError("%s: could not set breakpoint at line %"Pd" of '%s'",
                           CURRENT_FUNC, line, script_url.ToCString());
  } else {
    *breakpoint = reinterpret_cast<Dart_Breakpoint>(bpt);
  }
  return result;
}


DART_EXPORT Dart_Handle Dart_GetBreakpointURL(intptr_t bp_id) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  Debugger* debugger = isolate->debugger();
  ASSERT(debugger != NULL);

  SourceBreakpoint* bpt = debugger->GetBreakpointById(bp_id);
  if (bpt == NULL) {
    return Api::NewError("%s: breakpoint with id %"Pd" does not exist",
                           CURRENT_FUNC, bp_id);
  }
  return Api::NewHandle(isolate, bpt->SourceUrl());
}


DART_EXPORT Dart_Handle Dart_GetBreakpointLine(intptr_t bp_id) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  Debugger* debugger = isolate->debugger();
  ASSERT(debugger != NULL);

  SourceBreakpoint* bpt = debugger->GetBreakpointById(bp_id);
  if (bpt == NULL) {
    return Api::NewError("%s: breakpoint with id %"Pd" does not exist",
                         CURRENT_FUNC, bp_id);
  }
  return Dart_NewInteger(bpt->LineNumber());
}


DART_EXPORT Dart_Handle Dart_SetBreakpointAtEntry(
                            Dart_Handle library_in,
                            Dart_Handle class_name_in,
                            Dart_Handle function_name_in,
                            Dart_Breakpoint* breakpoint) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(Library, library, library_in);
  UNWRAP_AND_CHECK_PARAM(String, class_name, class_name_in);
  UNWRAP_AND_CHECK_PARAM(String, function_name, function_name_in);
  CHECK_NOT_NULL(breakpoint);

  Dart_Handle state = Api::CheckIsolateState(isolate);
  if (::Dart_IsError(state)) {
    return state;
  }

  // Resolve the breakpoint target function.
  Debugger* debugger = isolate->debugger();
  const Function& bp_target = Function::Handle(
      debugger->ResolveFunction(library, class_name, function_name));
  if (bp_target.IsNull()) {
    const bool toplevel = class_name.Length() == 0;
    return Api::NewError("%s: could not find function '%s%s%s'",
                         CURRENT_FUNC,
                         toplevel ? "" : class_name.ToCString(),
                         toplevel ? "" : ".",
                         function_name.ToCString());
  }

  Dart_Handle result = Api::True(isolate);
  *breakpoint = NULL;

  SourceBreakpoint* bpt = debugger->SetBreakpointAtEntry(bp_target);
  if (bpt == NULL) {
    const char* target_name = Debugger::QualifiedFunctionName(bp_target);
    result = Api::NewError("%s: no breakpoint location found in '%s'",
                             CURRENT_FUNC, target_name);
  } else {
    *breakpoint = reinterpret_cast<Dart_Breakpoint>(bpt);
  }
  return result;
}


DART_EXPORT Dart_Handle Dart_OneTimeBreakAtEntry(
                            Dart_Handle library_in,
                            Dart_Handle class_name_in,
                            Dart_Handle function_name_in) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(Library, library, library_in);
  UNWRAP_AND_CHECK_PARAM(String, class_name, class_name_in);
  UNWRAP_AND_CHECK_PARAM(String, function_name, function_name_in);

  Dart_Handle state = Api::CheckIsolateState(isolate);
  if (::Dart_IsError(state)) {
    return state;
  }

  // Resolve the breakpoint target function.
  Debugger* debugger = isolate->debugger();
  const Function& bp_target = Function::Handle(
      debugger->ResolveFunction(library, class_name, function_name));
  if (bp_target.IsNull()) {
    const bool toplevel = class_name.Length() == 0;
    return Api::NewError("%s: could not find function '%s%s%s'",
                         CURRENT_FUNC,
                         toplevel ? "" : class_name.ToCString(),
                         toplevel ? "" : ".",
                         function_name.ToCString());
  }

  debugger->OneTimeBreakAtEntry(bp_target);
  return Api::True(isolate);
}





DART_EXPORT Dart_Handle Dart_RemoveBreakpoint(intptr_t bp_id) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  Debugger* debugger = isolate->debugger();
  ASSERT(debugger != NULL);

  isolate->debugger()->RemoveBreakpoint(bp_id);
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_DeleteBreakpoint(
                            Dart_Breakpoint breakpoint_in) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);

  CHECK_AND_CAST(SourceBreakpoint, breakpoint, breakpoint_in);
  isolate->debugger()->RemoveBreakpoint(breakpoint->id());
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_SetStepOver() {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  isolate->debugger()->SetStepOver();
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_SetStepInto() {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  isolate->debugger()->SetStepInto();
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_SetStepOut() {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  isolate->debugger()->SetStepOut();
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_GetInstanceFields(Dart_Handle object_in) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(Instance, obj, object_in);
  return Api::NewHandle(isolate, isolate->debugger()->GetInstanceFields(obj));
}


DART_EXPORT Dart_Handle Dart_GetStaticFields(Dart_Handle cls_in) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(Class, cls, cls_in);
  return Api::NewHandle(isolate, isolate->debugger()->GetStaticFields(cls));
}


DART_EXPORT Dart_Handle Dart_GetLibraryFields(intptr_t library_id) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  const Library& lib =
      Library::Handle(isolate, Library::GetLibrary(library_id));
  if (lib.IsNull()) {
    return Api::NewError("%s: %"Pd" is not a valid library id",
                         CURRENT_FUNC, library_id);
  }
  return Api::NewHandle(isolate, isolate->debugger()->GetLibraryFields(lib));
}


DART_EXPORT Dart_Handle Dart_GetGlobalVariables(intptr_t library_id) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  DARTSCOPE(isolate);
  const Library& lib = Library::Handle(Library::GetLibrary(library_id));
  if (lib.IsNull()) {
    return Api::NewError("%s: %"Pd" is not a valid library id",
                         CURRENT_FUNC, library_id);
  }
  return Api::NewHandle(isolate, isolate->debugger()->GetGlobalFields(lib));
}


DART_EXPORT Dart_Handle Dart_GetObjClass(Dart_Handle object_in) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(Instance, obj, object_in);
  return Api::NewHandle(isolate, obj.clazz());
}


DART_EXPORT Dart_Handle Dart_GetObjClassId(Dart_Handle object_in,
                                           intptr_t* class_id) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(Instance, obj, object_in);
  CHECK_NOT_NULL(class_id);
  *class_id = Class::Handle(obj.clazz()).id();
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_GetSuperclass(Dart_Handle cls_in) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(Class, cls, cls_in);
  return Api::NewHandle(isolate, cls.SuperClass());
}


DART_EXPORT Dart_Handle Dart_GetClassInfo(
                            intptr_t cls_id,
                            Dart_Handle* class_name,
                            intptr_t* library_id,
                            intptr_t* super_class_id,
                            Dart_Handle* static_fields) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  if (!isolate->class_table()->IsValidIndex(cls_id)) {
    return Api::NewError("%s: %"Pd" is not a valid class id",
                         CURRENT_FUNC, cls_id);
  }
  Class& cls = Class::Handle(isolate, isolate->class_table()->At(cls_id));
  if (class_name != NULL) {
    *class_name = Api::NewHandle(isolate, cls.Name());
  }
  if (library_id != NULL) {
    const Library& lib = Library::Handle(isolate, cls.library());
    *library_id = lib.index();
  }
  if (super_class_id != NULL) {
    *super_class_id = 0;
    Class& super_cls = Class::Handle(isolate, cls.SuperClass());
    if (!super_cls.IsNull()) {
      *super_class_id = super_cls.id();
    }
  }
  if (static_fields != NULL) {
    *static_fields =
        Api::NewHandle(isolate, isolate->debugger()->GetStaticFields(cls));
  }
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_ScriptGetSource(
                            intptr_t library_id,
                            Dart_Handle script_url_in) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  const Library& lib = Library::Handle(Library::GetLibrary(library_id));
  if (lib.IsNull()) {
    return Api::NewError("%s: %"Pd" is not a valid library id",
                         CURRENT_FUNC, library_id);
  }
  UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
  const Script& script = Script::Handle(lib.LookupScript(script_url));
  if (script.IsNull()) {
    return Api::NewError("%s: script '%s' not found in library '%s'",
                         CURRENT_FUNC, script_url.ToCString(),
                         String::Handle(lib.url()).ToCString());
  }
  return Api::NewHandle(isolate, script.Source());
}


DART_EXPORT Dart_Handle Dart_GetScriptSource(
                            Dart_Handle library_url_in,
                            Dart_Handle script_url_in) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(String, library_url, library_url_in);
  UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);

  const Library& library = Library::Handle(Library::LookupLibrary(library_url));
  if (library.IsNull()) {
    return Api::NewError("%s: library '%s' not found",
                         CURRENT_FUNC, library_url.ToCString());
  }

  const Script& script = Script::Handle(library.LookupScript(script_url));
  if (script.IsNull()) {
    return Api::NewError("%s: script '%s' not found in library '%s'",
                         CURRENT_FUNC, script_url.ToCString(),
                         library_url.ToCString());
  }

  return Api::NewHandle(isolate, script.Source());
}


DART_EXPORT Dart_Handle Dart_GetScriptURLs(Dart_Handle library_url_in) {
  Isolate* isolate = Isolate::Current();
  DARTSCOPE(isolate);
  UNWRAP_AND_CHECK_PARAM(String, library_url, library_url_in);

  const Library& library = Library::Handle(Library::LookupLibrary(library_url));
  if (library.IsNull()) {
    return Api::NewError("%s: library '%s' not found",
                         CURRENT_FUNC, library_url.ToCString());
  }
  const Array& loaded_scripts = Array::Handle(library.LoadedScripts());
  ASSERT(!loaded_scripts.IsNull());
  intptr_t num_scripts = loaded_scripts.Length();
  const Array& script_list = Array::Handle(Array::New(num_scripts));
  Script& script = Script::Handle();
  String& url = String::Handle();
  for (int i = 0; i < num_scripts; i++) {
    script ^= loaded_scripts.At(i);
    url = script.url();
    script_list.SetAt(i, url);
  }
  return Api::NewHandle(isolate, script_list.raw());
}


DART_EXPORT Dart_Handle Dart_GetLibraryIds() {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  DARTSCOPE(isolate);

  const GrowableObjectArray& libs =
      GrowableObjectArray::Handle(isolate->object_store()->libraries());
  int num_libs = libs.Length();

  // Create new list and populate with the url of loaded libraries.
  Library &lib = Library::Handle();
  const Array& library_id_list = Array::Handle(Array::New(num_libs));
  for (int i = 0; i < num_libs; i++) {
    lib ^= libs.At(i);
    ASSERT(!lib.IsNull());
    ASSERT(Smi::IsValid(lib.index()));
    library_id_list.SetAt(i, Smi::Handle(Smi::New(lib.index())));
  }
  return Api::NewHandle(isolate, library_id_list.raw());
}


DART_EXPORT Dart_Handle Dart_GetLibraryImports(intptr_t library_id) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  DARTSCOPE(isolate);
  const Library& lib = Library::Handle(Library::GetLibrary(library_id));
  if (lib.IsNull()) {
    return Api::NewError("%s: %"Pd" is not a valid library id",
                         CURRENT_FUNC, library_id);
  }
  const GrowableObjectArray& import_list =
      GrowableObjectArray::Handle(GrowableObjectArray::New(8));

  String& prefix_name = String::Handle(isolate);
  Library& imported = Library::Handle(isolate);
  intptr_t num_imports = lib.num_imports();
  for (int i = 0; i < num_imports; i++) {
    import_list.Add(prefix_name);  // Null prefix name means no prefix.
    imported = lib.ImportLibraryAt(i);
    ASSERT(!imported.IsNull());
    ASSERT(Smi::IsValid(imported.index()));
    import_list.Add(Smi::Handle(Smi::New(imported.index())));
  }
  LibraryPrefixIterator it(lib);
  LibraryPrefix& prefix = LibraryPrefix::Handle(isolate);
  while (it.HasNext()) {
    prefix = it.GetNext();
    prefix_name = prefix.name();
    ASSERT(!prefix_name.IsNull());
    prefix_name = String::Concat(prefix_name, Symbols::Dot());
    for (int i = 0; i < prefix.num_imports(); i++) {
      imported = prefix.GetLibrary(i);
      import_list.Add(prefix_name);
      import_list.Add(Smi::Handle(Smi::New(imported.index())));
    }
  }
  return Api::NewHandle(isolate, Array::MakeArray(import_list));
}


DART_EXPORT Dart_Handle Dart_GetLibraryURL(intptr_t library_id) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  DARTSCOPE(isolate);
  const Library& lib = Library::Handle(Library::GetLibrary(library_id));
  if (lib.IsNull()) {
    return Api::NewError("%s: %"Pd" is not a valid library id",
                         CURRENT_FUNC, library_id);
  }
  return Api::NewHandle(isolate, lib.url());
}


DART_EXPORT Dart_Handle Dart_GetLibraryURLs() {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  DARTSCOPE(isolate);

  const GrowableObjectArray& libs =
      GrowableObjectArray::Handle(isolate->object_store()->libraries());
  int num_libs = libs.Length();

  // Create new list and populate with the url of loaded libraries.
  Library &lib = Library::Handle();
  String& lib_url = String::Handle();
  const Array& library_url_list = Array::Handle(Array::New(num_libs));
  for (int i = 0; i < num_libs; i++) {
    lib ^= libs.At(i);
    ASSERT(!lib.IsNull());
    lib_url = lib.url();
    library_url_list.SetAt(i, lib_url);
  }
  return Api::NewHandle(isolate, library_url_list.raw());
}


DART_EXPORT Dart_Handle Dart_GetLibraryDebuggable(intptr_t library_id,
                                                  bool* is_debuggable) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  DARTSCOPE(isolate);
  CHECK_NOT_NULL(is_debuggable);
  const Library& lib = Library::Handle(Library::GetLibrary(library_id));
  if (lib.IsNull()) {
    return Api::NewError("%s: %"Pd" is not a valid library id",
                         CURRENT_FUNC, library_id);
  }
  *is_debuggable = lib.IsDebuggable();
  return Api::True(isolate);
}


DART_EXPORT Dart_Handle Dart_SetLibraryDebuggable(intptr_t library_id,
                                                  bool is_debuggable) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  DARTSCOPE(isolate);
  const Library& lib = Library::Handle(Library::GetLibrary(library_id));
  if (lib.IsNull()) {
    return Api::NewError("%s: %"Pd" is not a valid library id",
                         CURRENT_FUNC, library_id);
  }
  lib.set_debuggable(is_debuggable);
  return Api::True(isolate);
}


DART_EXPORT Dart_Isolate Dart_GetIsolate(Dart_IsolateId isolate_id) {
  Isolate* isolate = PortMap::GetIsolate(isolate_id);
  return Api::CastIsolate(isolate);
}


DART_EXPORT char* Dart_GetVmStatus(const char* request) {
  if (strncmp(request, "/isolate/", 9) == 0) {
    return Isolate::GetStatus(request);
  }
  return NULL;
}

}  // namespace dart
