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

#include "platform/assert.h"

#include "include/dart_native_api.h"
#include "platform/unicode.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
#include "vm/heap/safepoint.h"
#include "vm/json_stream.h"
#include "vm/message.h"
#include "vm/metrics.h"
#include "vm/object.h"
#include "vm/service.h"
#include "vm/service_event.h"
#include "vm/thread_registry.h"
#include "vm/timeline.h"

namespace dart {

#ifndef PRODUCT

DECLARE_FLAG(bool, trace_service);

JSONStream::JSONStream(intptr_t buf_size)
    : writer_(buf_size),
      default_id_zone_(),
      id_zone_(&default_id_zone_),
      reply_port_(ILLEGAL_PORT),
      seq_(NULL),
      parameter_keys_(NULL),
      parameter_values_(NULL),
      method_(""),
      param_keys_(NULL),
      param_values_(NULL),
      num_params_(0),
      offset_(0),
      count_(-1) {
  ObjectIdRing* ring = NULL;
  Isolate* isolate = Isolate::Current();
  if (isolate != NULL) {
    ring = isolate->EnsureObjectIdRing();
  }
  default_id_zone_.Init(ring, ObjectIdRing::kAllocateId);
}

void JSONStream::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) {
  set_reply_port(reply_port);
  seq_ = &Instance::ZoneHandle(seq.ptr());
  method_ = method.ToCString();

  if (parameters_are_dart_objects) {
    parameter_keys_ = &Array::ZoneHandle(param_keys.ptr());
    parameter_values_ = &Array::ZoneHandle(param_values.ptr());
    ASSERT(parameter_keys_->Length() == parameter_values_->Length());
  } else if (param_keys.Length() > 0) {
    String& string_iterator = String::Handle();
    ASSERT(param_keys.Length() == param_values.Length());
    const char** param_keys_native =
        zone->Alloc<const char*>(param_keys.Length());
    const char** param_values_native =
        zone->Alloc<const char*>(param_keys.Length());
    for (intptr_t i = 0; i < param_keys.Length(); i++) {
      string_iterator ^= param_keys.At(i);
      param_keys_native[i] =
          zone->MakeCopyOfString(string_iterator.ToCString());
      string_iterator ^= param_values.At(i);
      param_values_native[i] =
          zone->MakeCopyOfString(string_iterator.ToCString());
    }
    SetParams(param_keys_native, param_values_native, param_keys.Length());
  }

  if (FLAG_trace_service) {
    Isolate* isolate = Isolate::Current();
    ASSERT(isolate != NULL);
    int64_t main_port = static_cast<int64_t>(isolate->main_port());
    const char* isolate_name = isolate->name();
    setup_time_micros_ = OS::GetCurrentTimeMicros();
    OS::PrintErr("[+%" Pd64 "ms] Isolate (%" Pd64
                 ") %s processing service "
                 "request %s\n",
                 Dart::UptimeMillis(), main_port, isolate_name, method_);
  }
  buffer()->Printf("{\"jsonrpc\":\"2.0\", \"result\":");
}

void JSONStream::SetupError() {
  Clear();
  buffer()->Printf("{\"jsonrpc\":\"2.0\", \"error\":");
}

static const char* GetJSONRpcErrorMessage(intptr_t code) {
  switch (code) {
    case kParseError:
      return "Parse error";
    case kInvalidRequest:
      return "Invalid Request";
    case kMethodNotFound:
      return "Method not found";
    case kInvalidParams:
      return "Invalid params";
    case kInternalError:
      return "Internal error";
    case kFeatureDisabled:
      return "Feature is disabled";
    case kCannotAddBreakpoint:
      return "Cannot add breakpoint";
    case kStreamAlreadySubscribed:
      return "Stream already subscribed";
    case kStreamNotSubscribed:
      return "Stream not subscribed";
    case kIsolateMustBeRunnable:
      return "Isolate must be runnable";
    case kIsolateMustBePaused:
      return "Isolate must be paused";
    case kCannotResume:
      return "Cannot resume execution";
    case kIsolateIsReloading:
      return "Isolate is reloading";
    case kIsolateReloadBarred:
      return "Isolate cannot be reloaded";
    case kIsolateMustHaveReloaded:
      return "Isolate must have reloaded";
    case kFileSystemAlreadyExists:
      return "File system already exists";
    case kFileSystemDoesNotExist:
      return "File system does not exist";
    case kFileDoesNotExist:
      return "File does not exist";
    case kInvalidTimelineRequest:
      return "The timeline related request could not be completed due to the "
             "current configuration";
    default:
      return "Extension error";
  }
}

static void PrintRequest(JSONObject* obj, JSONStream* js) {
  JSONObject jsobj(obj, "request");
  jsobj.AddProperty("method", js->method());
  {
    JSONObject params(&jsobj, "params");
    for (intptr_t i = 0; i < js->num_params(); i++) {
      params.AddProperty(js->GetParamKey(i), js->GetParamValue(i));
    }
  }
}

void JSONStream::PrintError(intptr_t code, const char* details_format, ...) {
  SetupError();
  JSONObject jsobj(this);
  jsobj.AddProperty("code", code);
  jsobj.AddProperty("message", GetJSONRpcErrorMessage(code));
  {
    JSONObject data(&jsobj, "data");
    PrintRequest(&data, this);
    if (details_format != NULL) {
      va_list args;
      va_start(args, details_format);
      intptr_t len = Utils::VSNPrint(NULL, 0, details_format, args);
      va_end(args);

      char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1);
      va_list args2;
      va_start(args2, details_format);
      Utils::VSNPrint(buffer, (len + 1), details_format, args2);
      va_end(args2);
      data.AddProperty("details", buffer);
    }
  }
}

void JSONStream::PostNullReply(Dart_Port port) {
  PortMap::PostMessage(
      Message::New(port, Object::null(), Message::kNormalPriority));
}

static void Finalizer(void* isolate_callback_data, void* buffer) {
  free(buffer);
}

void JSONStream::PostReply() {
  ASSERT(seq_ != NULL);
  Dart_Port port = reply_port();
  set_reply_port(ILLEGAL_PORT);  // Prevent double replies.
  if (seq_->IsString()) {
    const String& str = String::Cast(*seq_);
    PrintProperty("id", str.ToCString());
  } else if (seq_->IsInteger()) {
    const Integer& integer = Integer::Cast(*seq_);
    PrintProperty64("id", integer.AsInt64Value());
  } else if (seq_->IsDouble()) {
    const Double& dbl = Double::Cast(*seq_);
    PrintProperty("id", dbl.value());
  } else if (seq_->IsNull()) {
    if (port == ILLEGAL_PORT) {
      // This path is only used in tests.
      buffer()->AddChar('}');  // Finish our message.
      char* cstr;
      intptr_t length;
      Steal(&cstr, &length);
      OS::PrintErr("-----\nDropping reply:\n%s\n-----\n", cstr);
      free(cstr);
    }
    // JSON-RPC 2.0 says that a request with a null ID shouldn't get a reply.
    PostNullReply(port);
    return;
  }
  ASSERT(port != ILLEGAL_PORT);

  buffer()->AddChar('}');  // Finish our message.
  char* cstr;
  intptr_t length;
  Steal(&cstr, &length);

  bool result;
  {
    TransitionVMToNative transition(Thread::Current());
    Dart_CObject bytes;
    bytes.type = Dart_CObject_kExternalTypedData;
    bytes.value.as_external_typed_data.type = Dart_TypedData_kUint8;
    bytes.value.as_external_typed_data.length = length;
    bytes.value.as_external_typed_data.data = reinterpret_cast<uint8_t*>(cstr);
    bytes.value.as_external_typed_data.peer = cstr;
    bytes.value.as_external_typed_data.callback = Finalizer;
    Dart_CObject* elements[1];
    elements[0] = &bytes;
    Dart_CObject message;
    message.type = Dart_CObject_kArray;
    message.value.as_array.length = 1;
    message.value.as_array.values = elements;
    result = Dart_PostCObject(port, &message);
  }

  if (!result) {
    free(cstr);
  }

  if (FLAG_trace_service) {
    Isolate* isolate = Isolate::Current();
    ASSERT(isolate != NULL);
    int64_t main_port = static_cast<int64_t>(isolate->main_port());
    const char* isolate_name = isolate->name();
    int64_t total_time = OS::GetCurrentTimeMicros() - setup_time_micros_;
    if (result) {
      OS::PrintErr("[+%" Pd64 "ms] Isolate (%" Pd64
                   ") %s processed service request %s (%" Pd64 "us)\n",
                   Dart::UptimeMillis(), main_port, isolate_name, method_,
                   total_time);
    } else {
      OS::PrintErr("[+%" Pd64 "ms] Isolate (%" Pd64
                   ") %s processed service request %s (%" Pd64 "us) FAILED\n",
                   Dart::UptimeMillis(), main_port, isolate_name, method_,
                   total_time);
    }
  }
}

const char* JSONStream::LookupParam(const char* key) const {
  for (int i = 0; i < num_params(); i++) {
    if (strcmp(key, param_keys_[i]) == 0) {
      return param_values_[i];
    }
  }
  return NULL;
}

bool JSONStream::HasParam(const char* key) const {
  ASSERT(key);
  return LookupParam(key) != NULL;
}

bool JSONStream::ParamIs(const char* key, const char* value) const {
  ASSERT(key);
  ASSERT(value);
  const char* key_value = LookupParam(key);
  return (key_value != NULL) && (strcmp(key_value, value) == 0);
}

void JSONStream::ComputeOffsetAndCount(intptr_t length,
                                       intptr_t* offset,
                                       intptr_t* count) {
  // This function is written to avoid adding (count + offset) in case
  // that triggers an integer overflow.
  *offset = offset_;
  if (*offset > length) {
    *offset = length;
  }
  intptr_t remaining = length - *offset;
  *count = count_;
  if (*count < 0 || *count > remaining) {
    *count = remaining;
  }
}
void JSONStream::PrintfValue(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VPrintfValue(format, args);
  va_end(args);
}

void JSONStream::PrintValue(const Object& o, bool ref) {
  PrintCommaIfNeeded();
  o.PrintJSON(this, ref);
}

void JSONStream::PrintValue(Breakpoint* bpt) {
  PrintCommaIfNeeded();
  bpt->PrintJSON(this);
}

void JSONStream::PrintValue(TokenPosition tp) {
  PrintCommaIfNeeded();
  PrintValue(static_cast<intptr_t>(tp.Serialize()));
}

void JSONStream::PrintValue(const ServiceEvent* event) {
  PrintCommaIfNeeded();
  event->PrintJSON(this);
}

void JSONStream::PrintValue(Metric* metric) {
  PrintCommaIfNeeded();
  metric->PrintJSON(this);
}

void JSONStream::PrintValue(MessageQueue* queue) {
  PrintCommaIfNeeded();
  queue->PrintJSON(this);
}

void JSONStream::PrintValue(Isolate* isolate, bool ref) {
  PrintCommaIfNeeded();
  isolate->PrintJSON(this, ref);
}

void JSONStream::PrintValue(IsolateGroup* isolate_group, bool ref) {
  PrintCommaIfNeeded();
  isolate_group->PrintJSON(this, ref);
}

void JSONStream::PrintValue(const TimelineEvent* timeline_event) {
  PrintCommaIfNeeded();
  timeline_event->PrintJSON(this);
}

void JSONStream::PrintValue(const TimelineEventBlock* timeline_event_block) {
  PrintCommaIfNeeded();
  timeline_event_block->PrintJSON(this);
}

void JSONStream::PrintValueVM(bool ref) {
  PrintCommaIfNeeded();
  Service::PrintJSONForVM(this, ref);
}

void JSONStream::PrintServiceId(const Object& o) {
  ASSERT(id_zone_ != NULL);
  PrintProperty("id", id_zone_->GetServiceId(o));
}

void JSONStream::PrintProperty(const char* name, const ServiceEvent* event) {
  PrintPropertyName(name);
  PrintValue(event);
}

void JSONStream::PrintProperty(const char* name, Breakpoint* bpt) {
  PrintPropertyName(name);
  PrintValue(bpt);
}

void JSONStream::PrintProperty(const char* name, TokenPosition tp) {
  PrintPropertyName(name);
  PrintValue(tp);
}

void JSONStream::PrintProperty(const char* name, Metric* metric) {
  PrintPropertyName(name);
  PrintValue(metric);
}

void JSONStream::PrintProperty(const char* name, MessageQueue* queue) {
  PrintPropertyName(name);
  PrintValue(queue);
}

void JSONStream::PrintProperty(const char* name, Isolate* isolate) {
  PrintPropertyName(name);
  PrintValue(isolate);
}

void JSONStream::PrintProperty(const char* name,
                               const TimelineEvent* timeline_event) {
  PrintPropertyName(name);
  PrintValue(timeline_event);
}

void JSONStream::PrintProperty(const char* name,
                               const TimelineEventBlock* timeline_event_block) {
  PrintPropertyName(name);
  PrintValue(timeline_event_block);
}

void JSONStream::PrintfProperty(const char* name, const char* format, ...) {
  va_list args;
  va_start(args, format);
  writer_.VPrintfProperty(name, format, args);
  va_end(args);
}

void JSONStream::set_reply_port(Dart_Port port) {
  reply_port_ = port;
}

intptr_t JSONStream::NumObjectParameters() const {
  if (parameter_keys_ == NULL) {
    return 0;
  }
  ASSERT(parameter_keys_ != NULL);
  ASSERT(parameter_values_ != NULL);
  return parameter_keys_->Length();
}

ObjectPtr JSONStream::GetObjectParameterKey(intptr_t i) const {
  ASSERT((i >= 0) && (i < NumObjectParameters()));
  return parameter_keys_->At(i);
}

ObjectPtr JSONStream::GetObjectParameterValue(intptr_t i) const {
  ASSERT((i >= 0) && (i < NumObjectParameters()));
  return parameter_values_->At(i);
}

ObjectPtr JSONStream::LookupObjectParam(const char* c_key) const {
  const String& key = String::Handle(String::New(c_key));
  Object& test = Object::Handle();
  const intptr_t num_object_parameters = NumObjectParameters();
  for (intptr_t i = 0; i < num_object_parameters; i++) {
    test = GetObjectParameterKey(i);
    if (test.IsString() && String::Cast(test).Equals(key)) {
      return GetObjectParameterValue(i);
    }
  }
  return Object::null();
}

void JSONStream::SetParams(const char** param_keys,
                           const char** param_values,
                           intptr_t num_params) {
  param_keys_ = param_keys;
  param_values_ = param_values;
  num_params_ = num_params;
}

void JSONStream::PrintProperty(const char* name, const Object& o, bool ref) {
  PrintPropertyName(name);
  PrintValue(o, ref);
}

void JSONStream::PrintPropertyVM(const char* name, bool ref) {
  PrintPropertyName(name);
  PrintValueVM(ref);
}

JSONObject::JSONObject(const JSONArray* arr) : stream_(arr->stream_) {
  stream_->OpenObject();
}

void JSONObject::AddFixedServiceId(const char* format, ...) const {
  // Mark that this id is fixed.
  AddProperty("fixedId", true);
  // Add the id property.
  va_list args;
  va_start(args, format);
  stream_->VPrintfProperty("id", format, args);
  va_end(args);
}

void JSONObject::AddServiceId(const char* format, ...) const {
  // Add the id property.
  va_list args;
  va_start(args, format);
  stream_->VPrintfProperty("id", format, args);
  va_end(args);
}

void JSONObject::AddLocation(const Script& script,
                             TokenPosition token_pos,
                             TokenPosition end_token_pos) const {
  JSONObject location(this, "location");
  location.AddProperty("type", "SourceLocation");
  location.AddProperty("script", script);
  location.AddProperty("tokenPos", token_pos);
  if (end_token_pos.IsReal()) {
    location.AddProperty("endTokenPos", end_token_pos);
  }
}

void JSONObject::AddLocation(const BreakpointLocation* bpt_loc) const {
  ASSERT(bpt_loc->IsResolved());

  Zone* zone = Thread::Current()->zone();
  Script& script = Script::Handle(zone);
  TokenPosition token_pos = TokenPosition::kNoSource;
  bpt_loc->GetCodeLocation(&script, &token_pos);
  AddLocation(script, token_pos);
}

void JSONObject::AddUnresolvedLocation(
    const BreakpointLocation* bpt_loc) const {
  ASSERT(!bpt_loc->IsResolved());

  Zone* zone = Thread::Current()->zone();
  Script& script = Script::Handle(zone);
  TokenPosition token_pos = TokenPosition::kNoSource;
  bpt_loc->GetCodeLocation(&script, &token_pos);

  JSONObject location(this, "location");
  location.AddProperty("type", "UnresolvedSourceLocation");
  if (!script.IsNull()) {
    location.AddProperty("script", script);
  } else {
    const String& scriptUri = String::Handle(zone, bpt_loc->url());
    location.AddPropertyStr("scriptUri", scriptUri);
  }
  if (bpt_loc->requested_line_number() >= 0) {
    // This unresolved breakpoint was specified at a particular line.
    location.AddProperty("line", bpt_loc->requested_line_number());
    if (bpt_loc->requested_column_number() >= 0) {
      location.AddProperty("column", bpt_loc->requested_column_number());
    }
  } else {
    // This unresolved breakpoint was requested at some function entry.
    location.AddProperty("tokenPos", token_pos);
  }
}

void JSONObject::AddPropertyF(const char* name, const char* format, ...) const {
  va_list args;
  va_start(args, format);
  stream_->VPrintfProperty(name, format, args);
  va_end(args);
}

void JSONArray::AddValueF(const char* format, ...) const {
  va_list args;
  va_start(args, format);
  stream_->VPrintfValue(format, args);
  va_end(args);
}

#endif  // !PRODUCT

}  // namespace dart
