// Copyright 2018 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/api/api-inl.h"
#include "src/builtins/builtins-utils-inl.h"
#include "src/builtins/builtins.h"
#include "src/heap/heap-inl.h"  // For ToBoolean. TODO(jkummerow): Drop.
#include "src/json/json-stringifier.h"
#include "src/logging/counters.h"
#include "src/objects/objects-inl.h"

#if defined(V8_USE_PERFETTO)
#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
#include "src/base/platform/wrappers.h"
#endif

namespace v8 {
namespace internal {

namespace {

using v8::tracing::TracedValue;

#define MAX_STACK_LENGTH 100

class MaybeUtf8 {
 public:
  explicit MaybeUtf8(Isolate* isolate, Handle<String> string) : buf_(data_) {
    string = String::Flatten(isolate, string);
    int len;
    if (string->IsOneByteRepresentation()) {
      // Technically this allows unescaped latin1 characters but the trace
      // events mechanism currently does the same and the current consuming
      // tools are tolerant of it. A more correct approach here would be to
      // escape non-ascii characters but this is easier and faster.
      len = string->length();
      AllocateSufficientSpace(len);
      if (len > 0) {
        // Why copy? Well, the trace event mechanism requires null-terminated
        // strings, the bytes we get from SeqOneByteString are not. buf_ is
        // guaranteed to be null terminated.
        DisallowHeapAllocation no_gc;
        base::Memcpy(
            buf_, Handle<SeqOneByteString>::cast(string)->GetChars(no_gc), len);
      }
    } else {
      Local<v8::String> local = Utils::ToLocal(string);
      auto* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
      len = local->Utf8Length(v8_isolate);
      AllocateSufficientSpace(len);
      if (len > 0) {
        local->WriteUtf8(v8_isolate, reinterpret_cast<char*>(buf_));
      }
    }
    buf_[len] = 0;
  }
  const char* operator*() const { return reinterpret_cast<const char*>(buf_); }

 private:
  void AllocateSufficientSpace(int len) {
    if (len + 1 > MAX_STACK_LENGTH) {
      allocated_.reset(new uint8_t[len + 1]);
      buf_ = allocated_.get();
    }
  }

  // In the most common cases, the buffer here will be stack allocated.
  // A heap allocation will only occur if the data is more than MAX_STACK_LENGTH
  // Given that this is used primarily for trace event categories and names,
  // the MAX_STACK_LENGTH should be more than enough.
  uint8_t* buf_;
  uint8_t data_[MAX_STACK_LENGTH];
  std::unique_ptr<uint8_t> allocated_;
};

#if !defined(V8_USE_PERFETTO)
class JsonTraceValue : public ConvertableToTraceFormat {
 public:
  explicit JsonTraceValue(Isolate* isolate, Handle<String> object) {
    // object is a JSON string serialized using JSON.stringify() from within
    // the BUILTIN(Trace) method. This may (likely) contain UTF8 values so
    // to grab the appropriate buffer data we have to serialize it out. We
    // hold on to the bits until the AppendAsTraceFormat method is called.
    MaybeUtf8 data(isolate, object);
    data_ = *data;
  }

  void AppendAsTraceFormat(std::string* out) const override { *out += data_; }

 private:
  std::string data_;
};

const uint8_t* GetCategoryGroupEnabled(Isolate* isolate,
                                       Handle<String> string) {
  MaybeUtf8 category(isolate, string);
  return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(*category);
}
#endif  // !defined(V8_USE_PERFETTO)

#undef MAX_STACK_LENGTH

}  // namespace

// Builins::kIsTraceCategoryEnabled(category) : bool
BUILTIN(IsTraceCategoryEnabled) {
  HandleScope scope(isolate);
  Handle<Object> category = args.atOrUndefined(isolate, 1);
  if (!category->IsString()) {
    THROW_NEW_ERROR_RETURN_FAILURE(
        isolate, NewTypeError(MessageTemplate::kTraceEventCategoryError));
  }
  bool enabled;
#if defined(V8_USE_PERFETTO)
  MaybeUtf8 category_str(isolate, Handle<String>::cast(category));
  perfetto::DynamicCategory dynamic_category{*category_str};
  enabled = TRACE_EVENT_CATEGORY_ENABLED(dynamic_category);
#else
  enabled = *GetCategoryGroupEnabled(isolate, Handle<String>::cast(category));
#endif
  return isolate->heap()->ToBoolean(enabled);
}

// Builtins::kTrace(phase, category, name, id, data) : bool
BUILTIN(Trace) {
  HandleScope handle_scope(isolate);

  Handle<Object> phase_arg = args.atOrUndefined(isolate, 1);
  Handle<Object> category = args.atOrUndefined(isolate, 2);
  Handle<Object> name_arg = args.atOrUndefined(isolate, 3);
  Handle<Object> id_arg = args.atOrUndefined(isolate, 4);
  Handle<Object> data_arg = args.atOrUndefined(isolate, 5);

  // Exit early if the category group is not enabled.
#if defined(V8_USE_PERFETTO)
  MaybeUtf8 category_str(isolate, Handle<String>::cast(category));
  perfetto::DynamicCategory dynamic_category{*category_str};
  if (!TRACE_EVENT_CATEGORY_ENABLED(dynamic_category))
    return ReadOnlyRoots(isolate).false_value();
#else
  const uint8_t* category_group_enabled =
      GetCategoryGroupEnabled(isolate, Handle<String>::cast(category));
  if (!*category_group_enabled) return ReadOnlyRoots(isolate).false_value();
#endif

  if (!phase_arg->IsNumber()) {
    THROW_NEW_ERROR_RETURN_FAILURE(
        isolate, NewTypeError(MessageTemplate::kTraceEventPhaseError));
  }
  char phase = static_cast<char>(DoubleToInt32(phase_arg->Number()));
  if (!category->IsString()) {
    THROW_NEW_ERROR_RETURN_FAILURE(
        isolate, NewTypeError(MessageTemplate::kTraceEventCategoryError));
  }
  if (!name_arg->IsString()) {
    THROW_NEW_ERROR_RETURN_FAILURE(
        isolate, NewTypeError(MessageTemplate::kTraceEventNameError));
  }

  uint32_t flags = TRACE_EVENT_FLAG_COPY;
  int32_t id = 0;
  if (!id_arg->IsNullOrUndefined(isolate)) {
    if (!id_arg->IsNumber()) {
      THROW_NEW_ERROR_RETURN_FAILURE(
          isolate, NewTypeError(MessageTemplate::kTraceEventIDError));
    }
    flags |= TRACE_EVENT_FLAG_HAS_ID;
    id = DoubleToInt32(id_arg->Number());
  }

  Handle<String> name_str = Handle<String>::cast(name_arg);
  if (name_str->length() == 0) {
    THROW_NEW_ERROR_RETURN_FAILURE(
        isolate, NewTypeError(MessageTemplate::kTraceEventNameLengthError));
  }
  MaybeUtf8 name(isolate, name_str);

  // We support passing one additional trace event argument with the
  // name "data". Any JSON serializable value may be passed.
  static const char* arg_name = "data";
  Handle<Object> arg_json;
  int32_t num_args = 0;
  if (!data_arg->IsUndefined(isolate)) {
    // Serializes the data argument as a JSON string, which is then
    // copied into an object. This eliminates duplicated code but
    // could have perf costs. It is also subject to all the same
    // limitations as JSON.stringify() as it relates to circular
    // references and value limitations (e.g. BigInt is not supported).
    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
        isolate, arg_json,
        JsonStringify(isolate, data_arg, isolate->factory()->undefined_value(),
                      isolate->factory()->undefined_value()));
    num_args++;
  }

#if defined(V8_USE_PERFETTO)
  auto trace_args = [&](perfetto::EventContext ctx) {
    // TODO(skyostil): Use interned names to reduce trace size.
    if (phase != TRACE_EVENT_PHASE_END) {
      ctx.event()->set_name(*name);
    }
    if (num_args) {
      MaybeUtf8 arg_contents(isolate, Handle<String>::cast(arg_json));
      auto annotation = ctx.event()->add_debug_annotations();
      annotation->set_name(arg_name);
      annotation->set_legacy_json_value(*arg_contents);
    }
    if (flags & TRACE_EVENT_FLAG_HAS_ID) {
      auto legacy_event = ctx.event()->set_legacy_event();
      legacy_event->set_global_id(id);
    }
  };

  switch (phase) {
    case TRACE_EVENT_PHASE_BEGIN:
      TRACE_EVENT_BEGIN(dynamic_category, nullptr, trace_args);
      break;
    case TRACE_EVENT_PHASE_END:
      TRACE_EVENT_END(dynamic_category, trace_args);
      break;
    case TRACE_EVENT_PHASE_INSTANT:
      TRACE_EVENT_INSTANT(dynamic_category, nullptr, trace_args);
      break;
    default:
      THROW_NEW_ERROR_RETURN_FAILURE(
          isolate, NewTypeError(MessageTemplate::kTraceEventPhaseError));
  }

#else   // !defined(V8_USE_PERFETTO)
  uint8_t arg_type;
  uint64_t arg_value;
  if (num_args) {
    std::unique_ptr<JsonTraceValue> traced_value(
        new JsonTraceValue(isolate, Handle<String>::cast(arg_json)));
    tracing::SetTraceValue(std::move(traced_value), &arg_type, &arg_value);
  }

  TRACE_EVENT_API_ADD_TRACE_EVENT(
      phase, category_group_enabled, *name, tracing::kGlobalScope, id,
      tracing::kNoId, num_args, &arg_name, &arg_type, &arg_value, flags);
#endif  // !defined(V8_USE_PERFETTO)

  return ReadOnlyRoots(isolate).true_value();
}

}  // namespace internal
}  // namespace v8
