// 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 "vm/isolate.h"
#include "vm/json_stream.h"
#include "vm/object.h"
#include "vm/os.h"
#include "vm/trace_buffer.h"

namespace dart {

TraceBuffer::TraceBuffer(Isolate* isolate, intptr_t capacity)
    : isolate_(isolate), ring_capacity_(capacity) {
  ring_cursor_ = 0;
  ring_ = reinterpret_cast<TraceBufferEntry*>(
      calloc(ring_capacity_, sizeof(TraceBufferEntry)));  // NOLINT
}


TraceBuffer::~TraceBuffer() {
  ASSERT(ring_ != NULL);
  Clear();
  free(ring_);
  if (isolate_ != NULL) {
    isolate_->set_trace_buffer(NULL);
    isolate_ = NULL;
  }
}


void TraceBuffer::Init(Isolate* isolate, intptr_t capacity) {
  TraceBuffer* trace_buffer = new TraceBuffer(isolate, capacity);
  isolate->set_trace_buffer(trace_buffer);
}


void TraceBuffer::Clear() {
  for (intptr_t i = 0; i < ring_capacity_; i++) {
    TraceBufferEntry& entry = ring_[i];
    entry.micros = 0;
    free(entry.message);
    entry.message = NULL;
    entry.message_is_escaped = false;
  }
  ring_cursor_ = 0;
}


void TraceBuffer::Fill(TraceBufferEntry* entry, int64_t micros,
                       char* msg, bool msg_is_escaped) {
  if (entry->message != NULL) {
    // Recycle TraceBufferEntry.
    free(entry->message);
  }
  entry->message = msg;
  entry->message_is_escaped = msg_is_escaped;
  entry->micros = micros;
}


void TraceBuffer::AppendTrace(int64_t micros, char* msg, bool msg_is_escaped) {
  const intptr_t index = ring_cursor_;
  TraceBufferEntry* trace_entry = &ring_[index];
  Fill(trace_entry, micros, msg, msg_is_escaped);
  ring_cursor_ = RingIndex(ring_cursor_ + 1);
}


void TraceBuffer::Trace(int64_t micros, const char* msg, bool msg_is_escaped) {
  ASSERT(msg != NULL);
  char* message_copy = strdup(msg);
  AppendTrace(micros, message_copy, msg_is_escaped);
}


void TraceBuffer::Trace(const char* msg, bool msg_is_escaped) {
  Trace(OS::GetCurrentTimeMicros(), msg, msg_is_escaped);
}


void TraceBuffer::TraceF(const char* format, ...) {
  const int64_t micros = OS::GetCurrentTimeMicros();
  va_list args;
  va_start(args, format);
  const intptr_t len = OS::VSNPrint(NULL, 0, format, args);
  va_end(args);
  char* p = reinterpret_cast<char*>(malloc(len+1));
  va_start(args, format);
  const intptr_t len2 = OS::VSNPrint(p, len+1, format, args);
  va_end(args);
  ASSERT(len == len2);
  AppendTrace(micros, p);
}


void TraceBuffer::PrintToJSONStream(JSONStream* stream) const {
  JSONObject json_trace_buffer(stream);
  json_trace_buffer.AddProperty("type", "TraceBuffer");
  // TODO(johnmccutchan): Send cursor position in response.
  JSONArray json_trace_buffer_array(&json_trace_buffer, "members");
  // Scan forward until we find the first entry which isn't empty.
  // TODO(johnmccutchan): Accept cursor start position as input.
  intptr_t start = -1;
  for (intptr_t i = 0; i < ring_capacity_; i++) {
    intptr_t index = RingIndex(i + ring_cursor_);
    if (!ring_[index].empty()) {
      start = index;
      break;
    }
  }
  // No messages in trace buffer.
  if (start == -1) {
    return;
  }
  for (intptr_t i = 0; i < ring_capacity_; i++) {
    intptr_t index = RingIndex(start + i);
    const TraceBufferEntry& entry = ring_[index];
    if (entry.empty()) {
      // Empty entry, stop.
      break;
    }
    JSONObject trace_entry(&json_trace_buffer_array);
    trace_entry.AddProperty("type", "TraceBufferEntry");
    double seconds = static_cast<double>(entry.micros) /
                     static_cast<double>(kMicrosecondsPerSecond);
    trace_entry.AddProperty("time", seconds);
    if (entry.message_is_escaped) {
      trace_entry.AddPropertyNoEscape("message", entry.message);
    } else {
      trace_entry.AddProperty("message", entry.message);
    }
  }
}

}  // namespace dart
