// 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 RUNTIME_VM_SERVICE_EVENT_H_
#define RUNTIME_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
    kIsolateSpawn,           // Result of an isolate spawn request
    kServiceExtensionAdded,  // A service extension was registered

    kPauseStart,         // --pause-isolates-on-start
    kPauseExit,          // --pause-isolates-on-exit
    kPauseBreakpoint,
    kPauseInterrupted,
    kPauseException,
    kPausePostRequest,    // isolate is paused after a service request.
    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:
      case kPausePostRequest:
        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() == kPausePostRequest ||
           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;
  }

  const String* spawn_token() const {
    ASSERT(kind_ == kIsolateSpawn);
    return spawn_token_;
  }
  void set_spawn_token(const String* error) {
    ASSERT(kind_ == kIsolateSpawn);
    spawn_token_ = error;
  }

  const String* spawn_error() const {
    ASSERT(kind_ == kIsolateSpawn);
    return spawn_error_;
  }
  void set_spawn_error(const String* error) {
    ASSERT(kind_ == kIsolateSpawn);
    spawn_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_;
  const String* spawn_token_;
  const String* spawn_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  // RUNTIME_VM_SERVICE_EVENT_H_
