// 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();
      break;
  }
}

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

JSONTraceWriter::JSONTraceWriter(std::ostream& stream) : stream_(stream) {
  stream_ << "{\"traceEvents\":[";
}

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_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);
}

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