// Copyright (c) 2012 The Chromium 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 "base/debug/trace_event_impl.h"

#include <fcntl.h>

#include "base/debug/trace_event.h"
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"

namespace {

int g_atrace_fd = -1;
const char* kATraceMarkerFile = "/sys/kernel/debug/tracing/trace_marker";

void WriteEvent(
    char phase,
    const char* category_group,
    const char* name,
    unsigned long long id,
    int num_args,
    const char** arg_names,
    const unsigned char* arg_types,
    const unsigned long long* arg_values,
    const scoped_refptr<base::debug::ConvertableToTraceFormat>*
        convertable_values,
    unsigned char flags) {
  std::string out = base::StringPrintf("%c|%d|%s", phase, getpid(), name);
  if (flags & TRACE_EVENT_FLAG_HAS_ID)
    base::StringAppendF(&out, "-%" PRIx64, static_cast<uint64>(id));
  out += '|';

  for (int i = 0; i < num_args; ++i) {
    if (i)
      out += ';';
    out += arg_names[i];
    out += '=';
    std::string::size_type value_start = out.length();
    if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
      convertable_values[i]->AppendAsTraceFormat(&out);
    } else {
      base::debug::TraceEvent::TraceValue value;
      value.as_uint = arg_values[i];
      base::debug::TraceEvent::AppendValueAsJSON(arg_types[i], value, &out);
    }
    // Remove the quotes which may confuse the atrace script.
    ReplaceSubstringsAfterOffset(&out, value_start, "\\\"", "'");
    ReplaceSubstringsAfterOffset(&out, value_start, "\"", "");
    // Replace chars used for separators with similar chars in the value.
    std::replace(out.begin() + value_start, out.end(), ';', ',');
    std::replace(out.begin() + value_start, out.end(), '|', '!');
  }

  out += '|';
  out += category_group;
  write(g_atrace_fd, out.c_str(), out.size());
}

}  // namespace

namespace base {
namespace debug {

// These functions support Android systrace.py when 'webview' category is
// traced. With the new adb_profile_chrome, we may have two phases:
// - before WebView is ready for combined tracing, we can use adb_profile_chrome
//   to trace android categories other than 'webview' and chromium categories.
//   In this way we can avoid the conflict between StartATrace/StopATrace and
//   the intents.
// - TODO(wangxianzhu): after WebView is ready for combined tracing, remove
//   StartATrace, StopATrace and SendToATrace, and perhaps send Java traces
//   directly to atrace in trace_event_binding.cc.

void TraceLog::StartATrace() {
  if (g_atrace_fd != -1)
    return;

  g_atrace_fd = open(kATraceMarkerFile, O_WRONLY);
  if (g_atrace_fd == -1) {
    PLOG(WARNING) << "Couldn't open " << kATraceMarkerFile;
    return;
  }
  SetEnabled(CategoryFilter(CategoryFilter::kDefaultCategoryFilterString),
             RECORD_CONTINUOUSLY);
}

void TraceLog::StopATrace() {
  if (g_atrace_fd == -1)
    return;

  close(g_atrace_fd);
  g_atrace_fd = -1;
  SetDisabled();
  // Delete the buffered trace events as they have been sent to atrace.
  Flush(OutputCallback());
}

void TraceLog::SendToATrace(
    char phase,
    const char* category_group,
    const char* name,
    unsigned long long id,
    int num_args,
    const char** arg_names,
    const unsigned char* arg_types,
    const unsigned long long* arg_values,
    const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
    unsigned char flags) {
  if (g_atrace_fd == -1)
    return;

  switch (phase) {
    case TRACE_EVENT_PHASE_BEGIN:
      WriteEvent('B', category_group, name, id,
                 num_args, arg_names, arg_types, arg_values, convertable_values,
                 flags);
      break;

    case TRACE_EVENT_PHASE_END:
      // Though a single 'E' is enough, here append pid, name and
      // category_group etc. So that unpaired events can be found easily.
      WriteEvent('E', category_group, name, id,
                 num_args, arg_names, arg_types, arg_values, convertable_values,
                 flags);
      break;

    case TRACE_EVENT_PHASE_INSTANT:
      // Simulate an instance event with a pair of begin/end events.
      WriteEvent('B', category_group, name, id,
                 num_args, arg_names, arg_types, arg_values, convertable_values,
                 flags);
      write(g_atrace_fd, "E", 1);
      break;

    case TRACE_EVENT_PHASE_COUNTER:
      for (int i = 0; i < num_args; ++i) {
        DCHECK(arg_types[i] == TRACE_VALUE_TYPE_INT);
        std::string out = base::StringPrintf("C|%d|%s-%s",
                                       getpid(), name, arg_names[i]);
        if (flags & TRACE_EVENT_FLAG_HAS_ID)
          StringAppendF(&out, "-%" PRIx64, static_cast<uint64>(id));
        StringAppendF(&out, "|%d|%s",
                      static_cast<int>(arg_values[i]), category_group);
        write(g_atrace_fd, out.c_str(), out.size());
      }
      break;

    default:
      // Do nothing.
      break;
  }
}

void TraceLog::AddClockSyncMetadataEvent() {
  int atrace_fd = open(kATraceMarkerFile, O_WRONLY | O_APPEND);
  if (atrace_fd == -1) {
    PLOG(WARNING) << "Couldn't open " << kATraceMarkerFile;
    return;
  }

  // Android's kernel trace system has a trace_marker feature: this is a file on
  // debugfs that takes the written data and pushes it onto the trace
  // buffer. So, to establish clock sync, we write our monotonic clock into that
  // trace buffer.
  TimeTicks now = TimeTicks::NowFromSystemTraceTime();
  double now_in_seconds = now.ToInternalValue() / 1000000.0;
  std::string marker = StringPrintf(
      "trace_event_clock_sync: parent_ts=%f\n", now_in_seconds);
  if (write(atrace_fd, marker.c_str(), marker.size()) == -1)
    PLOG(WARNING) << "Couldn't write to " << kATraceMarkerFile;
  close(atrace_fd);
}

}  // namespace debug
}  // namespace base
