// Copyright (c) 2013, 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_JSON_STREAM_H_
#define RUNTIME_VM_JSON_STREAM_H_

#include "include/dart_api.h"  // for Dart_Port
#include "platform/allocation.h"
#include "platform/text_buffer.h"
#include "vm/json_writer.h"
#include "vm/service.h"
#include "vm/token_position.h"

namespace dart {

class Array;
class Breakpoint;
class BreakpointLocation;
class Field;
class GrowableObjectArray;
class Instance;
class JSONArray;
class JSONObject;
class MessageQueue;
class Metric;
class Object;
class Script;
class ServiceEvent;
class String;
class TimelineEvent;
class TimelineEventBlock;
class Thread;
class ThreadRegistry;
class Zone;

// Keep this enum in sync with:
//
//  - runtime/vm/service/vmservice.dart
//  - runtime/observatory/lib/src/service/object.dart
//
enum JSONRpcErrorCode {
  kParseError = -32700,
  kInvalidRequest = -32600,
  kMethodNotFound = -32601,
  kInvalidParams = -32602,
  kInternalError = -32603,

  kExtensionError = -32000,

  kFeatureDisabled = 100,
  kCannotAddBreakpoint = 102,
  kStreamAlreadySubscribed = 103,
  kStreamNotSubscribed = 104,
  kIsolateMustBeRunnable = 105,
  kIsolateMustBePaused = 106,
  kCannotResume = 107,
  kIsolateIsReloading = 108,
  kIsolateReloadBarred = 109,
  kIsolateMustHaveReloaded = 110,
  kServiceAlreadyRegistered = 111,
  kServiceDisappeared = 112,
  kExpressionCompilationError = 113,

  // Experimental (used in private rpcs).
  kFileSystemAlreadyExists = 1001,
  kFileSystemDoesNotExist = 1002,
  kFileDoesNotExist = 1003,
};

// Builds on JSONWriter to provide support for serializing various objects
// used in the VM service protocol.
class JSONStream : ValueObject {
 public:
  explicit JSONStream(intptr_t buf_size = 256);

  void Setup(Zone* zone,
             Dart_Port reply_port,
             const Instance& seq,
             const String& method,
             const Array& param_keys,
             const Array& param_values,
             bool parameters_are_dart_objects = false);
  void SetupError();

  void PrintError(intptr_t code, const char* details_format, ...)
      PRINTF_ATTRIBUTE(3, 4);

  void PostReply();

  void set_id_zone(ServiceIdZone* id_zone) { id_zone_ = id_zone; }
  ServiceIdZone* id_zone() { return id_zone_; }

  TextBuffer* buffer() { return writer_.buffer(); }
  const char* ToCString() { return writer_.ToCString(); }

  void Steal(char** buffer, intptr_t* buffer_length) {
    writer_.Steal(buffer, buffer_length);
  }

  void set_reply_port(Dart_Port port);

  void SetParams(const char** param_keys,
                 const char** param_values,
                 intptr_t num_params);

  Dart_Port reply_port() const { return reply_port_; }

  intptr_t NumObjectParameters() const;
  RawObject* GetObjectParameterKey(intptr_t i) const;
  RawObject* GetObjectParameterValue(intptr_t i) const;
  RawObject* LookupObjectParam(const char* key) const;

  intptr_t num_params() const { return num_params_; }
  const char* GetParamKey(intptr_t i) const { return param_keys_[i]; }
  const char* GetParamValue(intptr_t i) const { return param_values_[i]; }

  const char* LookupParam(const char* key) const;

  bool HasParam(const char* key) const;

  // Returns true if there is an param with key and value, false
  // otherwise.
  bool ParamIs(const char* key, const char* value) const;

  const char* method() const { return method_; }
  const char** param_keys() const { return param_keys_; }
  const char** param_values() const { return param_values_; }

  void set_offset(intptr_t value) {
    ASSERT(value > 0);
    offset_ = value;
  }

  void set_count(intptr_t value) {
    ASSERT(value > 0);
    count_ = value;
  }

  void ComputeOffsetAndCount(intptr_t length,
                             intptr_t* offset,
                             intptr_t* count);

  // Append |serialized_object| to the stream.
  void AppendSerializedObject(const char* serialized_object) {
    writer_.AppendSerializedObject(serialized_object);
  }

  // Append |buffer| to the stream.
  void AppendSerializedObject(const uint8_t* buffer, intptr_t buffer_length) {
    writer_.AppendSerializedObject(buffer, buffer_length);
  }

  // Append |serialized_object| to the stream with |property_name|.
  void AppendSerializedObject(const char* property_name,
                              const char* serialized_object) {
    writer_.AppendSerializedObject(property_name, serialized_object);
  }

  void PrintCommaIfNeeded() { writer_.PrintCommaIfNeeded(); }

 private:
  void Clear() { writer_.Clear(); }

  void PostNullReply(Dart_Port port);

  void OpenObject(const char* property_name = NULL) {
    writer_.OpenObject(property_name);
  }
  void CloseObject() { writer_.CloseObject(); }
  void UncloseObject() { writer_.UncloseObject(); }

  void OpenArray(const char* property_name = NULL) {
    writer_.OpenArray(property_name);
  }
  void CloseArray() { writer_.CloseArray(); }

  void PrintValueNull() { writer_.PrintValueNull(); }
  void PrintValueBool(bool b) { writer_.PrintValueBool(b); }
  void PrintValue(intptr_t i) { writer_.PrintValue(i); }
  void PrintValue64(int64_t i) { writer_.PrintValue64(i); }
  void PrintValueTimeMillis(int64_t millis) { writer_.PrintValue64(millis); }
  void PrintValueTimeMicros(int64_t micros) { writer_.PrintValue64(micros); }
  void PrintValue(double d) { writer_.PrintValue(d); }
  void PrintValueBase64(const uint8_t* bytes, intptr_t length) {
    writer_.PrintValueBase64(bytes, length);
  }
  void PrintValue(const char* s) { writer_.PrintValue(s); }
  void PrintValueNoEscape(const char* s) { writer_.PrintValueNoEscape(s); }
  bool PrintValueStr(const String& s, intptr_t offset, intptr_t count) {
    return writer_.PrintValueStr(s, offset, count);
  }
  void PrintfValue(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
  void VPrintfValue(const char* format, va_list args) {
    writer_.VPrintfValue(format, args);
  }

  void PrintValue(const Object& o, bool ref = true);
  void PrintValue(Breakpoint* bpt);
  void PrintValue(TokenPosition tp);
  void PrintValue(const ServiceEvent* event);
  void PrintValue(Metric* metric);
  void PrintValue(MessageQueue* queue);
  void PrintValue(Isolate* isolate, bool ref = true);
  void PrintValue(ThreadRegistry* reg);
  void PrintValue(Thread* thread);
  void PrintValue(const TimelineEvent* timeline_event);
  void PrintValue(const TimelineEventBlock* timeline_event_block);
  void PrintValueVM(bool ref = true);

  void PrintServiceId(const Object& o);

  void PrintPropertyBool(const char* name, bool b) {
    writer_.PrintPropertyBool(name, b);
  }
  void PrintProperty(const char* name, intptr_t i) {
    writer_.PrintProperty(name, i);
  }
  void PrintProperty64(const char* name, int64_t i) {
    writer_.PrintProperty64(name, i);
  }
  void PrintPropertyTimeMillis(const char* name, int64_t millis) {
    writer_.PrintProperty64(name, millis);
  }
  void PrintPropertyTimeMicros(const char* name, int64_t micros) {
    writer_.PrintProperty64(name, micros);
  }
  void PrintProperty(const char* name, double d) {
    writer_.PrintProperty(name, d);
  }
  void PrintPropertyBase64(const char* name,
                           const uint8_t* bytes,
                           intptr_t length) {
    writer_.PrintPropertyBase64(name, bytes, length);
  }
  void PrintProperty(const char* name, const char* s) {
    writer_.PrintProperty(name, s);
  }
  bool PrintPropertyStr(const char* name,
                        const String& s,
                        intptr_t offset,
                        intptr_t count) {
    return writer_.PrintPropertyStr(name, s, offset, count);
  }
  void PrintPropertyNoEscape(const char* name, const char* s) {
    writer_.PrintPropertyNoEscape(name, s);
  }
  void PrintfProperty(const char* name, const char* format, ...)
      PRINTF_ATTRIBUTE(3, 4);
  void VPrintfProperty(const char* name, const char* format, va_list args) {
    writer_.VPrintfProperty(name, format, args);
  }
  void PrintProperty(const char* name, const Object& o, bool ref = true);

  void PrintProperty(const char* name, const ServiceEvent* event);
  void PrintProperty(const char* name, Breakpoint* bpt);
  void PrintProperty(const char* name, TokenPosition tp);
  void PrintProperty(const char* name, Metric* metric);
  void PrintProperty(const char* name, MessageQueue* queue);
  void PrintProperty(const char* name, Isolate* isolate);
  void PrintProperty(const char* name, ThreadRegistry* reg);
  void PrintProperty(const char* name, Thread* thread);
  void PrintProperty(const char* name, Zone* zone);
  void PrintProperty(const char* name, const TimelineEvent* timeline_event);
  void PrintProperty(const char* name,
                     const TimelineEventBlock* timeline_event_block);
  void PrintPropertyVM(const char* name, bool ref = true);
  void PrintPropertyName(const char* name) { writer_.PrintPropertyName(name); }

  void AddEscapedUTF8String(const char* s, intptr_t len) {
    writer_.AddEscapedUTF8String(s, len);
  }

  JSONWriter writer_;
  // Default service id zone.
  RingServiceIdZone default_id_zone_;
  ServiceIdZone* id_zone_;
  Dart_Port reply_port_;
  Instance* seq_;
  Array* parameter_keys_;
  Array* parameter_values_;
  const char* method_;
  const char** param_keys_;
  const char** param_values_;
  intptr_t num_params_;
  intptr_t offset_;
  intptr_t count_;
  int64_t setup_time_micros_;

  friend class JSONObject;
  friend class JSONArray;
  friend class TimelineEvent;
};

class JSONObject : public ValueObject {
 public:
  explicit JSONObject(JSONStream* stream) : stream_(stream) {
    stream_->OpenObject();
  }
  JSONObject(const JSONObject* obj, const char* name) : stream_(obj->stream_) {
    stream_->OpenObject(name);
  }
  explicit JSONObject(const JSONArray* arr);

  ~JSONObject() { stream_->CloseObject(); }

  void AddServiceId(const Object& o) const { stream_->PrintServiceId(o); }

  void AddFixedServiceId(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);

  void AddLocation(
      const Script& script,
      TokenPosition token_pos,
      TokenPosition end_token_pos = TokenPosition::kNoSource) const;

  void AddLocation(const BreakpointLocation* bpt_loc) const;

  void AddUnresolvedLocation(const BreakpointLocation* bpt_loc) const;

  void AddProperty(const char* name, bool b) const {
    stream_->PrintPropertyBool(name, b);
  }
  void AddProperty(const char* name, intptr_t i) const {
    stream_->PrintProperty(name, i);
  }
  void AddProperty64(const char* name, int64_t i) const {
    stream_->PrintProperty64(name, i);
  }
  void AddPropertyTimeMillis(const char* name, int64_t millis) const {
    stream_->PrintPropertyTimeMillis(name, millis);
  }
  void AddPropertyTimeMicros(const char* name, int64_t micros) const {
    stream_->PrintPropertyTimeMicros(name, micros);
  }
  void AddProperty(const char* name, double d) const {
    stream_->PrintProperty(name, d);
  }
  void AddPropertyBase64(const char* name,
                         const uint8_t* bytes,
                         intptr_t length) const {
    stream_->PrintPropertyBase64(name, bytes, length);
  }
  void AddProperty(const char* name, const char* s) const {
    stream_->PrintProperty(name, s);
  }
  bool AddPropertyStr(const char* name,
                      const String& s,
                      intptr_t offset = 0,
                      intptr_t count = -1) const {
    return stream_->PrintPropertyStr(name, s, offset, count);
  }
  void AddPropertyNoEscape(const char* name, const char* s) const {
    stream_->PrintPropertyNoEscape(name, s);
  }
  void AddProperty(const char* name, const Object& obj, bool ref = true) const {
    stream_->PrintProperty(name, obj, ref);
  }
  void AddProperty(const char* name, const ServiceEvent* event) const {
    stream_->PrintProperty(name, event);
  }
  void AddProperty(const char* name, Breakpoint* bpt) const {
    stream_->PrintProperty(name, bpt);
  }
  void AddProperty(const char* name, TokenPosition tp) const {
    stream_->PrintProperty(name, tp);
  }
  void AddProperty(const char* name, Metric* metric) const {
    stream_->PrintProperty(name, metric);
  }
  void AddProperty(const char* name, MessageQueue* queue) const {
    stream_->PrintProperty(name, queue);
  }
  void AddProperty(const char* name, Isolate* isolate) const {
    stream_->PrintProperty(name, isolate);
  }
  void AddProperty(const char* name, ThreadRegistry* reg) const {
    stream_->PrintProperty(name, reg);
  }
  void AddProperty(const char* name, Thread* thread) const {
    stream_->PrintProperty(name, thread);
  }
  void AddProperty(const char* name, Zone* zone) const {
    stream_->PrintProperty(name, zone);
  }
  void AddProperty(const char* name,
                   const TimelineEvent* timeline_event) const {
    stream_->PrintProperty(name, timeline_event);
  }
  void AddProperty(const char* name,
                   const TimelineEventBlock* timeline_event_block) const {
    stream_->PrintProperty(name, timeline_event_block);
  }
  void AddPropertyVM(const char* name, bool ref = true) const {
    stream_->PrintPropertyVM(name, ref);
  }
  void AddPropertyF(const char* name, const char* format, ...) const
      PRINTF_ATTRIBUTE(3, 4);

 private:
  JSONStream* stream_;

  friend class JSONArray;

  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(JSONObject);
};

class JSONArray : public ValueObject {
 public:
  explicit JSONArray(JSONStream* stream) : stream_(stream) {
    stream_->OpenArray();
  }
  JSONArray(const JSONObject* obj, const char* name) : stream_(obj->stream_) {
    stream_->OpenArray(name);
  }
  explicit JSONArray(const JSONArray* arr) : stream_(arr->stream_) {
    stream_->OpenArray();
  }
  ~JSONArray() { stream_->CloseArray(); }

  void AddValueNull() const { stream_->PrintValueNull(); }
  void AddValue(bool b) const { stream_->PrintValueBool(b); }
  void AddValue(intptr_t i) const { stream_->PrintValue(i); }
  void AddValue64(int64_t i) const { stream_->PrintValue64(i); }
  void AddValueTimeMillis(int64_t millis) const {
    stream_->PrintValueTimeMillis(millis);
  }
  void AddValueTimeMicros(int64_t micros) const {
    stream_->PrintValueTimeMicros(micros);
  }
  void AddValue(double d) const { stream_->PrintValue(d); }
  void AddValue(const char* s) const { stream_->PrintValue(s); }
  void AddValue(const Object& obj, bool ref = true) const {
    stream_->PrintValue(obj, ref);
  }
  void AddValue(Isolate* isolate, bool ref = true) const {
    stream_->PrintValue(isolate, ref);
  }
  void AddValue(ThreadRegistry* reg) const { stream_->PrintValue(reg); }
  void AddValue(Thread* thread) const { stream_->PrintValue(thread); }
  void AddValue(Breakpoint* bpt) const { stream_->PrintValue(bpt); }
  void AddValue(TokenPosition tp) const { stream_->PrintValue(tp); }
  void AddValue(const ServiceEvent* event) const { stream_->PrintValue(event); }
  void AddValue(Metric* metric) const { stream_->PrintValue(metric); }
  void AddValue(MessageQueue* queue) const { stream_->PrintValue(queue); }
  void AddValue(const TimelineEvent* timeline_event) const {
    stream_->PrintValue(timeline_event);
  }
  void AddValue(const TimelineEventBlock* timeline_event_block) const {
    stream_->PrintValue(timeline_event_block);
  }
  void AddValueVM(bool ref = true) const { stream_->PrintValueVM(ref); }
  void AddValueF(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);

 private:
  JSONStream* stream_;

  friend class JSONObject;

  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(JSONArray);
};

}  // namespace dart

#endif  // RUNTIME_VM_JSON_STREAM_H_
