// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/service_event.h"

#include "vm/debugger.h"
#include "vm/message_handler.h"
#include "vm/service_isolate.h"
#include "vm/timeline.h"

namespace dart {

#ifndef PRODUCT

ServiceEvent::ServiceEvent(EventKind event_kind)
    : ServiceEvent(nullptr, nullptr, event_kind) {}

ServiceEvent::ServiceEvent(IsolateGroup* isolate_group, EventKind event_kind)
    : ServiceEvent(isolate_group, nullptr, event_kind) {}

ServiceEvent::ServiceEvent(Isolate* isolate, EventKind event_kind)
    : ServiceEvent(isolate != nullptr ? isolate->group() : nullptr,
                   isolate,
                   event_kind) {}

ServiceEvent::ServiceEvent(IsolateGroup* isolate_group,
                           Isolate* isolate,
                           EventKind event_kind)
    : isolate_(isolate),
      isolate_group_(isolate_group),
      kind_(event_kind),
      flag_name_(nullptr),
      flag_new_value_(nullptr),
      previous_tag_(nullptr),
      updated_tag_(nullptr),
      embedder_kind_(nullptr),
      embedder_stream_id_(nullptr),
      breakpoint_(nullptr),
      top_frame_(nullptr),
      timeline_event_block_(nullptr),
      extension_rpc_(nullptr),
      exception_(nullptr),
      reload_error_(nullptr),
      spawn_token_(nullptr),
      spawn_error_(nullptr),
      at_async_jump_(false),
      inspectee_(nullptr),
      gc_stats_(nullptr),
      bytes_(nullptr),
      bytes_length_(0),
      timestamp_(OS::GetCurrentTimeMillis()) {
  // We should never generate events for the vm isolate as it is never reported
  // over the service.
  ASSERT(isolate_ != Dart::vm_isolate());

  // VM internal isolates should never post service events. However, the Isolate
  // service object uses a service event to represent the current running state
  // of the isolate, so we need to allow for system isolates to create resume
  // and none events for this purpose. The resume event represents a running
  // isolate and the none event is returned for an isolate that has not yet
  // been marked as runnable (see "pauseEvent" in Isolate::PrintJSON).
  ASSERT(isolate == NULL || !Isolate::IsVMInternalIsolate(isolate) ||
         (Isolate::IsVMInternalIsolate(isolate) &&
          (event_kind == ServiceEvent::kResume ||
           event_kind == ServiceEvent::kNone ||
           // VM service can print Observatory information to Stdout or Stderr
           // which are embedder streams.
           event_kind == ServiceEvent::kEmbedder ||
           event_kind == ServiceEvent::kCpuSamples)));

  if ((event_kind == ServiceEvent::kPauseStart) ||
      (event_kind == ServiceEvent::kPauseExit)) {
    timestamp_ = isolate->message_handler()->paused_timestamp();
  } else if (event_kind == ServiceEvent::kResume) {
    timestamp_ = isolate->last_resume_timestamp();
  }
  ASSERT(timestamp_ > -1);
}

void ServiceEvent::UpdateTimestamp() {
  timestamp_ = OS::GetCurrentTimeMillis();
}

const char* ServiceEvent::KindAsCString() const {
  switch (kind()) {
    case kVMUpdate:
      return "VMUpdate";
    case kVMFlagUpdate:
      return "VMFlagUpdate";
    case kIsolateStart:
      return "IsolateStart";
    case kIsolateRunnable:
      return "IsolateRunnable";
    case kIsolateExit:
      return "IsolateExit";
    case kIsolateUpdate:
      return "IsolateUpdate";
    case kServiceExtensionAdded:
      return "ServiceExtensionAdded";
    case kIsolateReload:
      return "IsolateReload";
    case kPauseStart:
      return "PauseStart";
    case kPauseExit:
      return "PauseExit";
    case kPauseBreakpoint:
      return "PauseBreakpoint";
    case kPauseInterrupted:
      return "PauseInterrupted";
    case kPauseException:
      return "PauseException";
    case kPausePostRequest:
      return "PausePostRequest";
    case kNone:
      return "None";
    case kResume:
      return "Resume";
    case kBreakpointAdded:
      return "BreakpointAdded";
    case kBreakpointResolved:
      return "BreakpointResolved";
    case kBreakpointRemoved:
      return "BreakpointRemoved";
    case kBreakpointUpdated:
      return "BreakpointUpdated";
    case kGC:
      return "GC";  // TODO(koda): Change to GarbageCollected.
    case kInspect:
      return "Inspect";
    case kEmbedder:
      return embedder_kind();
    case kLogging:
      return "Logging";
    case kDebuggerSettingsUpdate:
      return "_DebuggerSettingsUpdate";
    case kIllegal:
      return "Illegal";
    case kExtension:
      return "Extension";
    case kTimelineEvents:
      return "TimelineEvents";
    case kTimelineStreamSubscriptionsUpdate:
      return "TimelineStreamSubscriptionsUpdate";
    case kUserTagChanged:
      return "UserTagChanged";
    case kCpuSamples:
      return "CpuSamples";
    default:
      UNREACHABLE();
      return "Unknown";
  }
}

const StreamInfo* ServiceEvent::stream_info() const {
  switch (kind()) {
    case kVMUpdate:
    case kVMFlagUpdate:
      return &Service::vm_stream;

    case kIsolateStart:
    case kIsolateRunnable:
    case kIsolateExit:
    case kIsolateUpdate:
    case kIsolateReload:
    case kServiceExtensionAdded:
      return &Service::isolate_stream;

    case kPauseStart:
    case kPauseExit:
    case kPauseBreakpoint:
    case kPauseInterrupted:
    case kPauseException:
    case kPausePostRequest:
    case kNone:
    case kResume:
    case kBreakpointAdded:
    case kBreakpointResolved:
    case kBreakpointRemoved:
    case kBreakpointUpdated:
    case kInspect:
    case kDebuggerSettingsUpdate:
      return &Service::debug_stream;

    case kGC:
      return &Service::gc_stream;

    case kLogging:
      return &Service::logging_stream;

    case kExtension:
      return &Service::extension_stream;

    case kTimelineEvents:
    case kTimelineStreamSubscriptionsUpdate:
      return &Service::timeline_stream;

    case kEmbedder:
      return nullptr;

    case kCpuSamples:
    case kUserTagChanged:
      return &Service::profiler_stream;

    default:
      UNREACHABLE();
      return nullptr;
  }
}

const char* ServiceEvent::stream_id() const {
  const StreamInfo* stream = stream_info();
  if (stream == NULL) {
    ASSERT(kind() == kEmbedder);
    return embedder_stream_id_;
  } else {
    return stream->id();
  }
}

void ServiceEvent::PrintJSON(JSONStream* js) const {
  JSONObject jsobj(js);
  PrintJSONHeader(&jsobj);
  if (kind() == kVMFlagUpdate) {
    jsobj.AddProperty("flag", flag_name());
    // For backwards compatibility, "new_value" is also provided.
    jsobj.AddProperty("newValue", flag_new_value());
  }
  if (kind() == kUserTagChanged) {
    jsobj.AddProperty("previousTag", previous_tag());
    jsobj.AddProperty("updatedTag", updated_tag());
  }
  if (kind() == kIsolateReload) {
    if (reload_error_ == NULL) {
      jsobj.AddProperty("status", "success");
    } else {
      jsobj.AddProperty("status", "failure");
      jsobj.AddProperty("reloadError", *(reload_error()));
    }
  }
  if (kind() == kServiceExtensionAdded) {
    ASSERT(extension_rpc_ != NULL);
    jsobj.AddProperty("extensionRPC", extension_rpc_->ToCString());
  }
  if (kind() == kPauseBreakpoint) {
    JSONArray jsarr(&jsobj, "pauseBreakpoints");
    // TODO(rmacnak): If we are paused at more than one breakpoint,
    // provide it here.
    if (breakpoint() != NULL) {
      jsarr.AddValue(breakpoint());
    }
  } else {
    if (breakpoint() != NULL) {
      jsobj.AddProperty("breakpoint", breakpoint());
    }
  }
  if (kind() == kTimelineEvents) {
    jsobj.AddProperty("timelineEvents", timeline_event_block_);
  }
  if (kind() == kTimelineStreamSubscriptionsUpdate) {
    JSONArray arr(&jsobj, "updatedStreams");
    Timeline::PrintFlagsToJSONArray(&arr);
  }
  if (kind() == kDebuggerSettingsUpdate) {
    JSONObject jssettings(&jsobj, "_debuggerSettings");
    isolate()->debugger()->PrintSettingsToJSONObject(&jssettings);
  }
#if !defined(DART_PRECOMPILED_RUNTIME)
  if (top_frame() != nullptr) {
    JSONObject jsFrame(&jsobj, "topFrame");
    top_frame()->PrintToJSONObject(&jsFrame);
    intptr_t index = 0;  // Avoid ambiguity in call to AddProperty.
    jsFrame.AddProperty("index", index);
  }
#endif
  if (exception() != NULL) {
    jsobj.AddProperty("exception", *(exception()));
  }
  if (at_async_jump()) {
    jsobj.AddProperty("atAsyncSuspension", true);
  }
  if (inspectee() != NULL) {
    jsobj.AddProperty("inspectee", *(inspectee()));
  }
  if (gc_stats() != NULL) {
    jsobj.AddProperty("reason", Heap::GCReasonToString(gc_stats()->reason_));
    isolate_group()->heap()->PrintToJSONObject(Heap::kNew, &jsobj);
    isolate_group()->heap()->PrintToJSONObject(Heap::kOld, &jsobj);
  }
  if (bytes() != NULL) {
    jsobj.AddPropertyBase64("bytes", bytes(), bytes_length());
  }
  if (kind() == kLogging) {
    JSONObject logRecord(&jsobj, "logRecord");
    logRecord.AddProperty("type", "LogRecord");
    logRecord.AddProperty64("sequenceNumber", log_record_.sequence_number);
    logRecord.AddPropertyTimeMillis("time", log_record_.timestamp);
    logRecord.AddProperty64("level", log_record_.level);
    logRecord.AddProperty("loggerName", *(log_record_.name));
    logRecord.AddProperty("message", *(log_record_.message));
    logRecord.AddProperty("zone", *(log_record_.zone));
    logRecord.AddProperty("error", *(log_record_.error));
    logRecord.AddProperty("stackTrace", *(log_record_.stack_trace));
  }
  if (kind() == kExtension) {
    js->AppendSerializedObject("extensionData",
                               extension_event_.event_data->ToCString());
  }

  if (kind() == kCpuSamples) {
    JSONObject cpu_profile(&jsobj, "cpuSamples");
    cpu_profile_->PrintProfileJSON(&cpu_profile, /*include_code_samples=*/false,
                                   /*is_event=*/true);
  }
}

void ServiceEvent::PrintJSONHeader(JSONObject* jsobj) const {
  ASSERT(jsobj != NULL);
  jsobj->AddProperty("type", "Event");
  jsobj->AddProperty("kind", KindAsCString());
  if (kind() == kExtension) {
    ASSERT(extension_event_.event_kind != NULL);
    jsobj->AddProperty("extensionKind",
                       extension_event_.event_kind->ToCString());
  }
  if (isolate() == NULL) {
    jsobj->AddPropertyVM("vm");
  } else {
    jsobj->AddProperty("isolate", isolate());
  }
  ASSERT(timestamp_ != -1);
  jsobj->AddPropertyTimeMillis("timestamp", timestamp_);
}

#endif  // !PRODUCT

}  // namespace dart
