// 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.

#ifndef VM_SERVICE_EVENT_H_
#define VM_SERVICE_EVENT_H_

#include "vm/globals.h"
#include "vm/heap.h"

namespace dart {

class ActivationFrame;
class Breakpoint;
class Instance;
class Isolate;
class Object;
class StreamInfo;
class String;
class TimelineEventBlock;

class ServiceEvent {
 public:
  enum EventKind {
    kVMUpdate,           // VM identity information has changed

    kIsolateStart,           // New isolate has started
    kIsolateRunnable,        // Isolate is ready to run
    kIsolateExit,            // Isolate has exited
    kIsolateUpdate,          // Isolate identity information has changed
    kIsolateReload,          // Result of a reload request
    kServiceExtensionAdded,  // A service extension was registered

    kPauseStart,         // --pause-isolates-on-start
    kPauseExit,          // --pause-isolates-on-exit
    kPauseBreakpoint,
    kPauseInterrupted,
    kPauseException,
    kNone,               // isolate has not been made runnable yet.
    kResume,
    kBreakpointAdded,
    kBreakpointResolved,
    kBreakpointRemoved,
    kInspect,
    kDebuggerSettingsUpdate,

    kGC,

    kEmbedder,

    kLogging,

    kExtension,

    kTimelineEvents,

    kIllegal,
  };

  struct LogRecord {
    int64_t sequence_number;
    int64_t timestamp;
    intptr_t level;
    const String* name;
    const String* message;
    const Instance* zone;
    const Object* error;
    const Instance* stack_trace;
  };

  struct ExtensionEvent {
    const String* event_kind;
    const String* event_data;
  };

  ServiceEvent(Isolate* isolate, EventKind event_kind);

  Isolate* isolate() const { return isolate_; }

  // Used by the C embedding api.
  Dart_Port isolate_id() const {
    return isolate_->main_port();
  }

  EventKind kind() const { return kind_; }

  bool IsPause() const {
    switch (kind())  {
      case kPauseStart:
      case kPauseExit:
      case kPauseBreakpoint:
      case kPauseInterrupted:
      case kPauseException:
        return true;
      default:
        return false;
    }
  }

  const char* embedder_kind() const { return embedder_kind_; }

  const char* KindAsCString() const;

  void set_embedder_kind(const char* embedder_kind) {
    embedder_kind_ = embedder_kind;
  }

  const StreamInfo* stream_info() const;
  const char* stream_id() const;

  void set_embedder_stream_id(const char* stream_id) {
    embedder_stream_id_ = stream_id;
  }

  Breakpoint* breakpoint() const {
    return breakpoint_;
  }
  void set_breakpoint(Breakpoint* bpt) {
    ASSERT(kind() == kPauseBreakpoint ||
           kind() == kBreakpointAdded ||
           kind() == kBreakpointResolved ||
           kind() == kBreakpointRemoved);
    breakpoint_ = bpt;
  }

  ActivationFrame* top_frame() const {
    return top_frame_;
  }
  void set_top_frame(ActivationFrame* frame) {
    ASSERT(kind() == kPauseBreakpoint ||
           kind() == kPauseInterrupted ||
           kind() == kPauseException ||
           kind() == kResume);
    top_frame_ = frame;
  }

  const String* extension_rpc() const {
    return extension_rpc_;
  }
  void set_extension_rpc(const String* extension_rpc) {
    extension_rpc_ = extension_rpc;
  }

  const Object* exception() const {
    return exception_;
  }
  void set_exception(const Object* exception) {
    ASSERT(kind_ == kPauseException);
    exception_ = exception;
  }

  const Error* reload_error() const {
    ASSERT(kind_ == kIsolateReload);
    return reload_error_;
  }
  void set_reload_error(const Error* error) {
    ASSERT(kind_ == kIsolateReload);
    reload_error_ = error;
  }

  bool at_async_jump() const {
    return at_async_jump_;
  }
  void set_at_async_jump(bool value) {
    at_async_jump_ = value;
  }

  const Object* inspectee() const {
    return inspectee_;
  }
  void set_inspectee(const Object* inspectee) {
    ASSERT(kind_ == kInspect);
    inspectee_ = inspectee;
  }

  const Heap::GCStats* gc_stats() const {
    return gc_stats_;
  }

  void set_gc_stats(const Heap::GCStats* gc_stats) {
    gc_stats_ = gc_stats;
  }

  const uint8_t* bytes() const {
    return bytes_;
  }

  intptr_t bytes_length() const {
    return bytes_length_;
  }

  void set_bytes(const uint8_t* bytes, intptr_t bytes_length) {
    bytes_ = bytes;
    bytes_length_ = bytes_length;
  }

  void set_log_record(const LogRecord& log_record) {
    log_record_ = log_record;
  }

  void set_extension_event(const ExtensionEvent& extension_event) {
    extension_event_ = extension_event;
  }

  void UpdateTimestamp();

  int64_t timestamp() const {
    return timestamp_;
  }

  const TimelineEventBlock* timeline_event_block() const {
    return timeline_event_block_;
  }

  void set_timeline_event_block(const TimelineEventBlock* block) {
    ASSERT(kind() == kTimelineEvents);
    timeline_event_block_ = block;
  }

  void PrintJSON(JSONStream* js) const;

  void PrintJSONHeader(JSONObject* jsobj) const;

 private:
  Isolate* isolate_;
  EventKind kind_;
  const char* embedder_kind_;
  const char* embedder_stream_id_;
  Breakpoint* breakpoint_;
  ActivationFrame* top_frame_;
  const TimelineEventBlock* timeline_event_block_;
  const String* extension_rpc_;
  const Object* exception_;
  const Error* reload_error_;
  bool at_async_jump_;
  const Object* inspectee_;
  const Heap::GCStats* gc_stats_;
  const uint8_t* bytes_;
  intptr_t bytes_length_;
  LogRecord log_record_;
  ExtensionEvent extension_event_;
  int64_t timestamp_;
};

}  // namespace dart

#endif  // VM_SERVICE_EVENT_H_
