// 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 "include/libplatform/v8-tracing.h"

#include "base/trace_event/common/trace_event_common.h"
#include "include/v8-platform.h"
#include "src/base/platform/platform.h"
#include "src/base/platform/time.h"

namespace v8 {
namespace platform {
namespace tracing {

// We perform checks for NULL strings since it is possible that a string arg
// value is NULL.
V8_INLINE static size_t GetAllocLength(const char* str) {
  return str ? strlen(str) + 1 : 0;
}

// Copies |*member| into |*buffer|, sets |*member| to point to this new
// location, and then advances |*buffer| by the amount written.
V8_INLINE static void CopyTraceObjectParameter(char** buffer,
                                               const char** member) {
  if (*member) {
    size_t length = strlen(*member) + 1;
    strncpy(*buffer, *member, length);
    *member = *buffer;
    *buffer += length;
  }
}

void TraceObject::Initialize(
    char phase, const uint8_t* category_enabled_flag, const char* name,
    const char* scope, uint64_t id, uint64_t bind_id, int num_args,
    const char** arg_names, const uint8_t* arg_types,
    const uint64_t* arg_values,
    std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
    unsigned int flags) {
  pid_ = base::OS::GetCurrentProcessId();
  tid_ = base::OS::GetCurrentThreadId();
  phase_ = phase;
  category_enabled_flag_ = category_enabled_flag;
  name_ = name;
  scope_ = scope;
  id_ = id;
  bind_id_ = bind_id;
  flags_ = flags;
  ts_ = base::TimeTicks::HighResolutionNow().ToInternalValue();
  tts_ = base::ThreadTicks::Now().ToInternalValue();
  duration_ = 0;
  cpu_duration_ = 0;

  // Clamp num_args since it may have been set by a third-party library.
  num_args_ = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args;
  for (int i = 0; i < num_args_; ++i) {
    arg_names_[i] = arg_names[i];
    arg_values_[i].as_uint = arg_values[i];
    arg_types_[i] = arg_types[i];
    if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE)
      arg_convertables_[i] = std::move(arg_convertables[i]);
  }

  bool copy = !!(flags & TRACE_EVENT_FLAG_COPY);
  // Allocate a long string to fit all string copies.
  size_t alloc_size = 0;
  if (copy) {
    alloc_size += GetAllocLength(name) + GetAllocLength(scope);
    for (int i = 0; i < num_args_; ++i) {
      alloc_size += GetAllocLength(arg_names_[i]);
      if (arg_types_[i] == TRACE_VALUE_TYPE_STRING)
        arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING;
    }
  }

  bool arg_is_copy[kTraceMaxNumArgs];
  for (int i = 0; i < num_args_; ++i) {
    // We only take a copy of arg_vals if they are of type COPY_STRING.
    arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING);
    if (arg_is_copy[i]) alloc_size += GetAllocLength(arg_values_[i].as_string);
  }

  if (alloc_size) {
    // Since TraceObject can be initialized multiple times, we might need
    // to free old memory.
    delete[] parameter_copy_storage_;
    char* ptr = parameter_copy_storage_ = new char[alloc_size];
    if (copy) {
      CopyTraceObjectParameter(&ptr, &name_);
      CopyTraceObjectParameter(&ptr, &scope_);
      for (int i = 0; i < num_args_; ++i) {
        CopyTraceObjectParameter(&ptr, &arg_names_[i]);
      }
    }
    for (int i = 0; i < num_args_; ++i) {
      if (arg_is_copy[i]) {
        CopyTraceObjectParameter(&ptr, &arg_values_[i].as_string);
      }
    }
  }
}

TraceObject::~TraceObject() { delete[] parameter_copy_storage_; }

void TraceObject::UpdateDuration() {
  duration_ = base::TimeTicks::HighResolutionNow().ToInternalValue() - ts_;
  cpu_duration_ = base::ThreadTicks::Now().ToInternalValue() - tts_;
}

void TraceObject::InitializeForTesting(
    char phase, const uint8_t* category_enabled_flag, const char* name,
    const char* scope, uint64_t id, uint64_t bind_id, int num_args,
    const char** arg_names, const uint8_t* arg_types,
    const uint64_t* arg_values,
    std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
    unsigned int flags, int pid, int tid, int64_t ts, int64_t tts,
    uint64_t duration, uint64_t cpu_duration) {
  pid_ = pid;
  tid_ = tid;
  phase_ = phase;
  category_enabled_flag_ = category_enabled_flag;
  name_ = name;
  scope_ = scope;
  id_ = id;
  bind_id_ = bind_id;
  num_args_ = num_args;
  flags_ = flags;
  ts_ = ts;
  tts_ = tts;
  duration_ = duration;
  cpu_duration_ = cpu_duration;
}

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