// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/trace_event/trace_event_impl.h"

#include <stddef.h>

#include <sstream>

#include "base/format_macros.h"
#include "base/json/string_escape.h"
#include "base/memory/ptr_util.h"
#include "base/notreached.h"
#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_log.h"
#include "base/trace_event/traced_value.h"
#include "build/build_config.h"

#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)

// Define static storage for trace event categories (see
// PERFETTO_DEFINE_CATEGORIES).
PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE_WITH_ATTRS(base, BASE_EXPORT);

namespace perfetto {
namespace legacy {

template <>
perfetto::ThreadTrack ConvertThreadId(const ::base::PlatformThreadId& thread) {
  return perfetto::ThreadTrack::ForThread(thread);
}

}  // namespace legacy

TraceTimestamp
TraceTimestampTraits<::base::TimeTicks>::ConvertTimestampToTraceTimeNs(
    const ::base::TimeTicks& ticks) {
  return {static_cast<uint32_t>(::base::TrackEvent::GetTraceClockId()),
          static_cast<uint64_t>(ticks.since_origin().InNanoseconds())};
}

namespace internal {

void WriteDebugAnnotation(protos::pbzero::DebugAnnotation* annotation,
                          ::base::TimeTicks ticks) {
  annotation->set_int_value(ticks.since_origin().InMilliseconds());
}

void WriteDebugAnnotation(protos::pbzero::DebugAnnotation* annotation,
                          ::base::Time time) {
  annotation->set_int_value(time.since_origin().InMilliseconds());
}

}  // namespace internal
}  // namespace perfetto

#endif  // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)

namespace base {
namespace trace_event {

bool ConvertableToTraceFormat::AppendToProto(ProtoAppender* appender) const {
  return false;
}

// See comment for name TraceEvent::scope_ definition.
static_assert(trace_event_internal::kGlobalScope == nullptr,
              "Invalid TraceEvent::scope default initializer value");

TraceEvent::TraceEvent() = default;

TraceEvent::TraceEvent(PlatformThreadId thread_id,
                       TimeTicks timestamp,
                       ThreadTicks thread_timestamp,
                       char phase,
                       const unsigned char* category_group_enabled,
                       const char* name,
                       const char* scope,
                       unsigned long long id,
                       unsigned long long bind_id,
                       TraceArguments* args,
                       unsigned int flags)
    : timestamp_(timestamp),
      thread_timestamp_(thread_timestamp),
      scope_(scope),
      id_(id),
      category_group_enabled_(category_group_enabled),
      name_(name),
      thread_id_(thread_id),
      flags_(flags),
      bind_id_(bind_id),
      phase_(phase) {
  InitArgs(args);
}

TraceEvent::~TraceEvent() = default;

TraceEvent::TraceEvent(TraceEvent&& other) noexcept = default;
TraceEvent& TraceEvent::operator=(TraceEvent&& other) noexcept = default;

void TraceEvent::Reset() {
  // Only reset fields that won't be initialized in Reset(int, ...), or that may
  // hold references to other objects.
  duration_ = TimeDelta::FromInternalValue(-1);
  args_.Reset();
  parameter_copy_storage_.Reset();
}

void TraceEvent::Reset(PlatformThreadId thread_id,
                       TimeTicks timestamp,
                       ThreadTicks thread_timestamp,
                       char phase,
                       const unsigned char* category_group_enabled,
                       const char* name,
                       const char* scope,
                       unsigned long long id,
                       unsigned long long bind_id,
                       TraceArguments* args,
                       unsigned int flags) {
  Reset();
  timestamp_ = timestamp;
  thread_timestamp_ = thread_timestamp;
  scope_ = scope;
  id_ = id;
  category_group_enabled_ = category_group_enabled;
  name_ = name;
  thread_id_ = thread_id;
  flags_ = flags;
  bind_id_ = bind_id;
  phase_ = phase;

  InitArgs(args);
}

void TraceEvent::InitArgs(TraceArguments* args) {
  if (args)
    args_ = std::move(*args);
  args_.CopyStringsTo(&parameter_copy_storage_,
                      !!(flags_ & TRACE_EVENT_FLAG_COPY), &name_, &scope_);
}

void TraceEvent::UpdateDuration(const TimeTicks& now,
                                const ThreadTicks& thread_now) {
  DCHECK_EQ(duration_.ToInternalValue(), -1);
  duration_ = now - timestamp_;

  // |thread_timestamp_| can be empty if the thread ticks clock wasn't
  // initialized when it was recorded.
  if (thread_timestamp_ != ThreadTicks())
    thread_duration_ = thread_now - thread_timestamp_;
}

void TraceEvent::EstimateTraceMemoryOverhead(
    TraceEventMemoryOverhead* overhead) {
  overhead->Add(TraceEventMemoryOverhead::kTraceEvent,
                parameter_copy_storage_.EstimateTraceMemoryOverhead());

  for (size_t i = 0; i < arg_size(); ++i) {
    if (arg_type(i) == TRACE_VALUE_TYPE_CONVERTABLE)
      arg_value(i).as_convertable->EstimateTraceMemoryOverhead(overhead);
  }
}

void TraceEvent::AppendAsJSON(
    std::string* out,
    const ArgumentFilterPredicate& argument_filter_predicate) const {
  int64_t time_int64 = timestamp_.ToInternalValue();
  ProcessId process_id;
  PlatformThreadId thread_id;
  if ((flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID) &&
      process_id_ != kNullProcessId) {
    process_id = process_id_;
    thread_id = static_cast<PlatformThreadId>(-1);
  } else {
    process_id = TraceLog::GetInstance()->process_id();
    thread_id = thread_id_;
  }
  const char* category_group_name =
      TraceLog::GetCategoryGroupName(category_group_enabled_);

  // Category group checked at category creation time.
  DCHECK(!strchr(name_, '"'));
  StringAppendF(out,
                "{\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64
                ",\"ph\":\"%c\",\"cat\":\"%s\",\"name\":",
                static_cast<int>(process_id), static_cast<int>(thread_id),
                time_int64, phase_, category_group_name);
  EscapeJSONString(name_, true, out);
  *out += ",\"args\":";

  // Output argument names and values, stop at first NULL argument name.
  // TODO(oysteine): The dual predicates here is a bit ugly; if the filtering
  // capabilities need to grow even more precise we should rethink this
  // approach
  ArgumentNameFilterPredicate argument_name_filter_predicate;
  bool strip_args =
      arg_size() > 0 && arg_name(0) && !argument_filter_predicate.is_null() &&
      !argument_filter_predicate.Run(category_group_name, name_,
                                     &argument_name_filter_predicate);

  if (strip_args) {
    *out += "\"__stripped__\"";
  } else {
    *out += "{";

    for (size_t i = 0; i < arg_size() && arg_name(i); ++i) {
      if (i > 0)
        *out += ",";
      *out += "\"";
      *out += arg_name(i);
      *out += "\":";

      if (argument_name_filter_predicate.is_null() ||
          argument_name_filter_predicate.Run(arg_name(i))) {
        arg_value(i).AppendAsJSON(arg_type(i), out);
      } else {
        *out += "\"__stripped__\"";
      }
    }

    *out += "}";
  }

  if (phase_ == TRACE_EVENT_PHASE_COMPLETE) {
    int64_t duration = duration_.ToInternalValue();
    if (duration != -1)
      StringAppendF(out, ",\"dur\":%" PRId64, duration);
    if (!thread_timestamp_.is_null()) {
      int64_t thread_duration = thread_duration_.ToInternalValue();
      if (thread_duration != -1)
        StringAppendF(out, ",\"tdur\":%" PRId64, thread_duration);
    }
  }

  // Output tts if thread_timestamp is valid.
  if (!thread_timestamp_.is_null()) {
    int64_t thread_time_int64 = thread_timestamp_.ToInternalValue();
    StringAppendF(out, ",\"tts\":%" PRId64, thread_time_int64);
  }

  // Output async tts marker field if flag is set.
  if (flags_ & TRACE_EVENT_FLAG_ASYNC_TTS) {
    StringAppendF(out, ", \"use_async_tts\":1");
  }

  // If id_ is set, print it out as a hex string so we don't loose any
  // bits (it might be a 64-bit pointer).
  unsigned int id_flags_ = flags_ & (TRACE_EVENT_FLAG_HAS_ID |
                                     TRACE_EVENT_FLAG_HAS_LOCAL_ID |
                                     TRACE_EVENT_FLAG_HAS_GLOBAL_ID);
  if (id_flags_) {
    if (scope_ != trace_event_internal::kGlobalScope)
      StringAppendF(out, ",\"scope\":\"%s\"", scope_);

    switch (id_flags_) {
      case TRACE_EVENT_FLAG_HAS_ID:
        StringAppendF(out, ",\"id\":\"0x%" PRIx64 "\"",
                      static_cast<uint64_t>(id_));
        break;

      case TRACE_EVENT_FLAG_HAS_LOCAL_ID:
        StringAppendF(out, ",\"id2\":{\"local\":\"0x%" PRIx64 "\"}",
                      static_cast<uint64_t>(id_));
        break;

      case TRACE_EVENT_FLAG_HAS_GLOBAL_ID:
        StringAppendF(out, ",\"id2\":{\"global\":\"0x%" PRIx64 "\"}",
                      static_cast<uint64_t>(id_));
        break;

      default:
        NOTREACHED() << "More than one of the ID flags are set";
        break;
    }
  }

  if (flags_ & TRACE_EVENT_FLAG_BIND_TO_ENCLOSING)
    StringAppendF(out, ",\"bp\":\"e\"");

  if ((flags_ & TRACE_EVENT_FLAG_FLOW_OUT) ||
      (flags_ & TRACE_EVENT_FLAG_FLOW_IN)) {
    StringAppendF(out, ",\"bind_id\":\"0x%" PRIx64 "\"",
                  static_cast<uint64_t>(bind_id_));
  }
  if (flags_ & TRACE_EVENT_FLAG_FLOW_IN)
    StringAppendF(out, ",\"flow_in\":true");
  if (flags_ & TRACE_EVENT_FLAG_FLOW_OUT)
    StringAppendF(out, ",\"flow_out\":true");

  // Instant events also output their scope.
  if (phase_ == TRACE_EVENT_PHASE_INSTANT) {
    char scope = '?';
    switch (flags_ & TRACE_EVENT_FLAG_SCOPE_MASK) {
      case TRACE_EVENT_SCOPE_GLOBAL:
        scope = TRACE_EVENT_SCOPE_NAME_GLOBAL;
        break;

      case TRACE_EVENT_SCOPE_PROCESS:
        scope = TRACE_EVENT_SCOPE_NAME_PROCESS;
        break;

      case TRACE_EVENT_SCOPE_THREAD:
        scope = TRACE_EVENT_SCOPE_NAME_THREAD;
        break;
    }
    StringAppendF(out, ",\"s\":\"%c\"", scope);
  }

  *out += "}";
}

void TraceEvent::AppendPrettyPrinted(std::ostringstream* out) const {
  *out << name_ << "[";
  *out << TraceLog::GetCategoryGroupName(category_group_enabled_);
  *out << "]";
  if (arg_size() > 0 && arg_name(0)) {
    *out << ", {";
    for (size_t i = 0; i < arg_size() && arg_name(i); ++i) {
      if (i > 0)
        *out << ", ";
      *out << arg_name(i) << ":";
      std::string value_as_text;
      arg_value(i).AppendAsJSON(arg_type(i), &value_as_text);
      *out << value_as_text;
    }
    *out << "}";
  }
}

}  // namespace trace_event
}  // namespace base
