// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/dart/embedder/dart_debugger.h"
#include "dart/runtime/include/dart_api.h"
#include "dart/runtime/include/dart_debugger_api.h"
#include "dart/runtime/include/dart_native_api.h"


namespace mojo {
namespace dart {

void DartDebuggerIsolate::MessageLoop() {
  MonitorLocker ml(&monitor_);
  // Request notification on isolate messages.  This allows us to
  // respond to vm service messages while at breakpoint.
  Dart_SetMessageNotifyCallback(DartDebugger::NotifyIsolate);
  while (true) {
    // Handle all available vm service messages, up to a resume
    // request.
    bool resume = false;
    while (!resume && Dart_HasServiceMessages()) {
      monitor_.Exit();
      resume = Dart_HandleServiceMessages();
      monitor_.Enter();
    }
    if (resume) {
      break;
    }
    ml.Wait();
  }
  Dart_SetMessageNotifyCallback(nullptr);
}

void DartDebugger::BptResolvedHandler(Dart_IsolateId isolate_id,
                                      intptr_t bp_id,
                                      const Dart_CodeLocation& location) {
  // Nothing to do here. Service event is dispatched to let Observatory know
  // that a breakpoint was resolved.
}

void DartDebugger::PausedEventHandler(Dart_IsolateId isolate_id,
                                      intptr_t bp_id,
                                      const Dart_CodeLocation& loc) {
  Dart_EnterScope();
  intptr_t isolate_index = FindIsolateIndexById(isolate_id);
  CHECK(isolate_index != -1);
  (*isolates_)[isolate_index]->MessageLoop();
  Dart_ExitScope();
}

void DartDebugger::ExceptionThrownHandler(Dart_IsolateId isolate_id,
                                          Dart_Handle exception,
                                          Dart_StackTrace stack_trace) {
  Dart_EnterScope();
  intptr_t isolate_index = FindIsolateIndexById(isolate_id);
  CHECK(isolate_index != -1);
  (*isolates_)[isolate_index]->MessageLoop();
  Dart_ExitScope();
}

void DartDebugger::IsolateEventHandler(Dart_IsolateId isolate_id,
                                       Dart_IsolateEvent kind) {
  Dart_EnterScope();
  if (kind == Dart_IsolateEvent::kCreated) {
    AddIsolate(isolate_id);
  } else {
    intptr_t isolate_index = FindIsolateIndexById(isolate_id);
    CHECK(isolate_index != -1);
    if (kind == Dart_IsolateEvent::kInterrupted) {
      (*isolates_)[isolate_index]->MessageLoop();
    } else {
      CHECK(kind == Dart_IsolateEvent::kShutdown);
      RemoveIsolate(isolate_id);
    }
  }
  Dart_ExitScope();
}

void DartDebugger::NotifyIsolate(Dart_Isolate isolate) {
  base::AutoLock al(*lock_);
  Dart_IsolateId isolate_id = Dart_GetIsolateId(isolate);
  intptr_t isolate_index = FindIsolateIndexByIdLocked(isolate_id);
  if (isolate_index >= 0) {
    (*isolates_)[isolate_index]->Notify();
  }
}

void DartDebugger::InitDebugger() {
  Dart_SetIsolateEventHandler(IsolateEventHandler);
  Dart_SetPausedEventHandler(PausedEventHandler);
  Dart_SetBreakpointResolvedHandler(BptResolvedHandler);
  Dart_SetExceptionThrownHandler(ExceptionThrownHandler);
  lock_ = new base::Lock();
  isolates_ = new std::vector<std::unique_ptr<DartDebuggerIsolate>>();
}

intptr_t DartDebugger::FindIsolateIndexById(Dart_IsolateId id) {
  base::AutoLock al(*lock_);
  return FindIsolateIndexByIdLocked(id);
}

intptr_t DartDebugger::FindIsolateIndexByIdLocked(
      Dart_IsolateId id) {
  lock_->AssertAcquired();
  for (size_t i = 0; i < isolates_->size(); i++) {
    if ((*isolates_)[i]->id() == id) {
      return i;
    }
  }
  return -1;
}

void DartDebugger::AddIsolate(Dart_IsolateId id) {
  base::AutoLock al(*lock_);
  CHECK(FindIsolateIndexByIdLocked(id) == -1);
  std::unique_ptr<DartDebuggerIsolate> debugger_isolate =
      std::unique_ptr<DartDebuggerIsolate>(new DartDebuggerIsolate(id));
  isolates_->push_back(std::move(debugger_isolate));
}

void DartDebugger::RemoveIsolate(Dart_IsolateId id) {
  base::AutoLock al(*lock_);
  for (size_t i = 0; i < isolates_->size(); i++) {
    if (id == (*isolates_)[i]->id()) {
      isolates_->erase(isolates_->begin() + i);
      return;
    }
  }
  NOTREACHED();
}

base::Lock* DartDebugger::lock_ = nullptr;
std::vector<std::unique_ptr<DartDebuggerIsolate>>* DartDebugger::isolates_ =
    nullptr;

}  // namespace dart
}  // namespace mojo
