// 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.


#ifndef BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
#define BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include "base/atomicops.h"
#include "base/base_export.h"
#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_local.h"
#include "base/trace_event/trace_event_memory_overhead.h"
#include "build/build_config.h"

namespace base {
namespace trace_event {

typedef base::Callback<bool(const char* arg_name)> ArgumentNameFilterPredicate;

typedef base::Callback<bool(const char* category_group_name,
                            const char* event_name,
                            ArgumentNameFilterPredicate*)>
    ArgumentFilterPredicate;

// For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
// class must implement this interface.
class BASE_EXPORT ConvertableToTraceFormat {
 public:
  ConvertableToTraceFormat() = default;
  virtual ~ConvertableToTraceFormat() = default;

  // Append the class info to the provided |out| string. The appended
  // data must be a valid JSON object. Strings must be properly quoted, and
  // escaped. There is no processing applied to the content after it is
  // appended.
  virtual void AppendAsTraceFormat(std::string* out) const = 0;

  virtual void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);

  std::string ToString() const {
    std::string result;
    AppendAsTraceFormat(&result);
    return result;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ConvertableToTraceFormat);
};

const int kTraceMaxNumArgs = 2;

struct TraceEventHandle {
  uint32_t chunk_seq;
  // These numbers of bits must be kept consistent with
  // TraceBufferChunk::kMaxTrunkIndex and
  // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h).
  unsigned chunk_index : 26;
  unsigned event_index : 6;
};

class BASE_EXPORT TraceEvent {
 public:
  union TraceValue {
    bool as_bool;
    unsigned long long as_uint;
    long long as_int;
    double as_double;
    const void* as_pointer;
    const char* as_string;
  };

  TraceEvent();
  ~TraceEvent();

  void MoveFrom(std::unique_ptr<TraceEvent> other);

  void Initialize(int 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,
                  int num_args,
                  const char* const* arg_names,
                  const unsigned char* arg_types,
                  const unsigned long long* arg_values,
                  std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
                  unsigned int flags);

  void Reset();

  void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now);

  void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);

  // Serialize event data to JSON
  void AppendAsJSON(
      std::string* out,
      const ArgumentFilterPredicate& argument_filter_predicate) const;
  void AppendPrettyPrinted(std::ostringstream* out) const;

  static void AppendValueAsJSON(unsigned char type,
                                TraceValue value,
                                std::string* out);

  TimeTicks timestamp() const { return timestamp_; }
  ThreadTicks thread_timestamp() const { return thread_timestamp_; }
  char phase() const { return phase_; }
  int thread_id() const { return thread_id_; }
  TimeDelta duration() const { return duration_; }
  TimeDelta thread_duration() const { return thread_duration_; }
  const char* scope() const { return scope_; }
  unsigned long long id() const { return id_; }
  unsigned int flags() const { return flags_; }
  unsigned long long bind_id() const { return bind_id_; }
  // Exposed for unittesting:

  const std::string* parameter_copy_storage() const {
    return parameter_copy_storage_.get();
  }

  const unsigned char* category_group_enabled() const {
    return category_group_enabled_;
  }

  const char* name() const { return name_; }

  unsigned char arg_type(size_t index) const { return arg_types_[index]; }
  const char* arg_name(size_t index) const { return arg_names_[index]; }
  const TraceValue& arg_value(size_t index) const { return arg_values_[index]; }

  const ConvertableToTraceFormat* arg_convertible_value(size_t index) const {
    return convertable_values_[index].get();
  }

#if defined(OS_ANDROID)
  void SendToATrace();
#endif

 private:
  // Note: these are ordered by size (largest first) for optimal packing.
  TimeTicks timestamp_;
  ThreadTicks thread_timestamp_;
  TimeDelta duration_;
  TimeDelta thread_duration_;
  // scope_ and id_ can be used to store phase-specific data.
  const char* scope_;
  unsigned long long id_;
  TraceValue arg_values_[kTraceMaxNumArgs];
  const char* arg_names_[kTraceMaxNumArgs];
  std::unique_ptr<ConvertableToTraceFormat>
      convertable_values_[kTraceMaxNumArgs];
  const unsigned char* category_group_enabled_;
  const char* name_;
  std::unique_ptr<std::string> parameter_copy_storage_;
  // Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either:
  //  tid: thread_id_, pid: current_process_id (default case).
  //  tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID).
  union {
    int thread_id_;
    int process_id_;
  };
  unsigned int flags_;
  unsigned long long bind_id_;
  unsigned char arg_types_[kTraceMaxNumArgs];
  char phase_;

  DISALLOW_COPY_AND_ASSIGN(TraceEvent);
};

}  // namespace trace_event
}  // namespace base

#endif  // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
