// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/libplatform/tracing/trace-writer.h"

#include <cmath>

#include "v8/src/tracing/trace_event_common.h"
#include "include/v8-platform.h"
#include "src/base/platform/platform.h"

namespace v8 {
namespace platform {
namespace tracing {

// Writes the given string to a stream, taking care to escape characters
// when necessary.
V8_INLINE static void WriteJSONStringToStream(const char* str,
                                              std::ostream& stream) {
  size_t len = strlen(str);
  stream << "\"";
  for (size_t i = 0; i < len; ++i) {
    // All of the permitted escape sequences in JSON strings, as per
    // https://mathiasbynens.be/notes/javascript-escapes
    switch (str[i]) {
      case '\b':
        stream << "\\b";
        break;
      case '\f':
        stream << "\\f";
        break;
      case '\n':
        stream << "\\n";
        break;
      case '\r':
        stream << "\\r";
        break;
      case '\t':
        stream << "\\t";
        break;
      case '\"':
        stream << "\\\"";
        break;
      case '\\':
        stream << "\\\\";
        break;
      // Note that because we use double quotes for JSON strings,
      // we don't need to escape single quotes.
      default:
        stream << str[i];
        break;
    }
  }
  stream << "\"";
}

void JSONTraceWriter::AppendArgValue(uint8_t type,
                                     TraceObject::ArgValue value) {
  switch (type) {
    case TRACE_VALUE_TYPE_BOOL:
      stream_ << (value.as_bool ? "true" : "false");
      break;
    case TRACE_VALUE_TYPE_UINT:
      stream_ << value.as_uint;
      break;
    case TRACE_VALUE_TYPE_INT:
      stream_ << value.as_int;
      break;
    case TRACE_VALUE_TYPE_DOUBLE: {
      std::string real;
      double val = value.as_double;
      if (std::isfinite(val)) {
        std::ostringstream convert_stream;
        convert_stream << val;
        real = convert_stream.str();
        // Ensure that the number has a .0 if there's no decimal or 'e'.  This
        // makes sure that when we read the JSON back, it's interpreted as a
        // real rather than an int.
        if (real.find('.') == std::string::npos &&
            real.find('e') == std::string::npos &&
            real.find('E') == std::string::npos) {
          real += ".0";
        }
      } else if (std::isnan(val)) {
        // The JSON spec doesn't allow NaN and Infinity (since these are
        // objects in EcmaScript).  Use strings instead.
        real = "\"NaN\"";
      } else if (val < 0) {
        real = "\"-Infinity\"";
      } else {
        real = "\"Infinity\"";
      }
      stream_ << real;
      break;
    }
    case TRACE_VALUE_TYPE_POINTER:
      // JSON only supports double and int numbers.
      // So as not to lose bits from a 64-bit pointer, output as a hex string.
      stream_ << "\"" << value.as_pointer << "\"";
      break;
    case TRACE_VALUE_TYPE_STRING:
    case TRACE_VALUE_TYPE_COPY_STRING:
      if (value.as_string == nullptr) {
        stream_ << "\"nullptr\"";
      } else {
        WriteJSONStringToStream(value.as_string, stream_);
      }
      break;
    default:
      UNREACHABLE();
  }
}

void JSONTraceWriter::AppendArgValue(ConvertableToTraceFormat* value) {
  std::string arg_stringified;
  value->AppendAsTraceFormat(&arg_stringified);
  stream_ << arg_stringified;
}

JSONTraceWriter::JSONTraceWriter(std::ostream& stream)
    : JSONTraceWriter(stream, "traceEvents") {}

JSONTraceWriter::JSONTraceWriter(std::ostream& stream, const std::string& tag)
    : stream_(stream) {
  stream_ << "{\"" << tag << "\":[";
}

JSONTraceWriter::~JSONTraceWriter() { stream_ << "]}"; }

void JSONTraceWriter::AppendTraceEvent(TraceObject* trace_event) {
  if (append_comma_) stream_ << ",";
  append_comma_ = true;
  stream_ << "{\"pid\":" << trace_event->pid()
          << ",\"tid\":" << trace_event->tid()
          << ",\"ts\":" << trace_event->ts()
          << ",\"tts\":" << trace_event->tts() << ",\"ph\":\""
          << trace_event->phase() << "\",\"cat\":\""
          << TracingController::GetCategoryGroupName(
                 trace_event->category_enabled_flag())
          << "\",\"name\":\"" << trace_event->name()
          << "\",\"dur\":" << trace_event->duration()
          << ",\"tdur\":" << trace_event->cpu_duration();
  if (trace_event->flags() &
      (TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT)) {
    stream_ << ",\"bind_id\":\"0x" << std::hex << trace_event->bind_id() << "\""
            << std::dec;
    if (trace_event->flags() & TRACE_EVENT_FLAG_FLOW_IN) {
      stream_ << ",\"flow_in\":true";
    }
    if (trace_event->flags() & TRACE_EVENT_FLAG_FLOW_OUT) {
      stream_ << ",\"flow_out\":true";
    }
  }
  if (trace_event->flags() & TRACE_EVENT_FLAG_HAS_ID) {
    if (trace_event->scope() != nullptr) {
      stream_ << ",\"scope\":\"" << trace_event->scope() << "\"";
    }
    // So as not to lose bits from a 64-bit integer, output as a hex string.
    stream_ << ",\"id\":\"0x" << std::hex << trace_event->id() << "\""
            << std::dec;
  }
  stream_ << ",\"args\":{";
  const char** arg_names = trace_event->arg_names();
  const uint8_t* arg_types = trace_event->arg_types();
  TraceObject::ArgValue* arg_values = trace_event->arg_values();
  std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables =
      trace_event->arg_convertables();
  for (int i = 0; i < trace_event->num_args(); ++i) {
    if (i > 0) stream_ << ",";
    stream_ << "\"" << arg_names[i] << "\":";
    if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
      AppendArgValue(arg_convertables[i].get());
    } else {
      AppendArgValue(arg_types[i], arg_values[i]);
    }
  }
  stream_ << "}}";
  // TODO(fmeawad): Add support for Flow Events.
}

void JSONTraceWriter::Flush() {}

TraceWriter* TraceWriter::CreateJSONTraceWriter(std::ostream& stream) {
  return new JSONTraceWriter(stream);
}

TraceWriter* TraceWriter::CreateJSONTraceWriter(std::ostream& stream,
                                                const std::string& tag) {
  return new JSONTraceWriter(stream, tag);
}

}  // namespace tracing
}  // namespace platform
}  // namespace v8
