// Copyright 2019 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 UTIL_TRACE_LOGGING_SCOPED_TRACE_OPERATIONS_H_
#define UTIL_TRACE_LOGGING_SCOPED_TRACE_OPERATIONS_H_

#include <atomic>
#include <cstring>
#include <memory>
#include <stack>
#include <utility>
#include <vector>

#include "platform/api/time.h"
#include "platform/base/error.h"
#include "platform/base/trace_logging_types.h"
#include "util/osp_logging.h"

#if defined(ENABLE_TRACE_LOGGING)

namespace openscreen {
namespace internal {

// A base class for all trace logging objects which will create new entries in
// the Trace Hierarchy.
// 1) The sharing of all static and thread_local variables across template
// specializations.
// 2) Including all children in the same traces vector.
class ScopedTraceOperation {
 public:
  // Define the destructor to remove this item from the stack when it's
  // destroyed.
  virtual ~ScopedTraceOperation();

  // Getters the current Trace Hierarchy. If the traces_ stack hasn't been
  // created yet, return as if the empty root node is there.
  static TraceId current_id() {
    return traces_ == nullptr ? kEmptyTraceId : traces_->top()->trace_id_;
  }

  static TraceId root_id() {
    return traces_ == nullptr ? kEmptyTraceId : traces_->top()->root_id_;
  }

  static TraceIdHierarchy hierarchy() {
    if (traces_ == nullptr) {
      return TraceIdHierarchy::Empty();
    }

    return traces_->top()->to_hierarchy();
  }

  // Static method to set the result of the most recent trace.
  static void set_result(const Error& error) { set_result(error.code()); }
  static void set_result(Error::Code error) {
    if (traces_ == nullptr) {
      return;
    }
    traces_->top()->SetTraceResult(error);
  }

  // Traces the end of an asynchronous call.
  // NOTE: This returns a bool rather than a void because it keeps the syntax of
  // the ternary operator in the macros simpler.
  static bool TraceAsyncEnd(const uint32_t line,
                            const char* file,
                            TraceId id,
                            Error::Code e);

 protected:
  // Sets the result of this trace log.
  // NOTE: this must be define in this class rather than TraceLogger so that it
  // can be called on traces.back() without a potentially unsafe cast or type
  // checking at runtime.
  virtual void SetTraceResult(Error::Code error) = 0;

  // Constructor to set all trace id information.
  ScopedTraceOperation(TraceId current_id = kUnsetTraceId,
                       TraceId parent_id = kUnsetTraceId,
                       TraceId root_id = kUnsetTraceId);

  // Current TraceId information.
  TraceId trace_id_;
  TraceId parent_id_;
  TraceId root_id_;

  TraceIdHierarchy to_hierarchy() { return {trace_id_, parent_id_, root_id_}; }

 private:
  // NOTE: A std::vector is used for backing the stack because it provides the
  // best perf. Further perf improvement could be achieved later by swapping
  // this out for a circular buffer once OSP supports that. Additional details
  // can be found here:
  // https://www.codeproject.com/Articles/1185449/Performance-of-a-Circular-Buffer-vs-Vector-Deque-a
  using TraceStack =
      std::stack<ScopedTraceOperation*, std::vector<ScopedTraceOperation*>>;

  // Counter to pick IDs when it is not provided.
  static std::atomic<std::uint64_t> trace_id_counter_;

  // The LIFO stack of TraceLoggers currently being watched by this
  // thread.
  static thread_local TraceStack* traces_;
  static thread_local ScopedTraceOperation* root_node_;

  OSP_DISALLOW_COPY_AND_ASSIGN(ScopedTraceOperation);
};

// The class which does actual trace logging.
class TraceLoggerBase : public ScopedTraceOperation {
 public:
  TraceLoggerBase(TraceCategory::Value category,
                  const char* name,
                  const char* file,
                  uint32_t line,
                  TraceId current = kUnsetTraceId,
                  TraceId parent = kUnsetTraceId,
                  TraceId root = kUnsetTraceId);

  TraceLoggerBase(TraceCategory::Value category,
                  const char* name,
                  const char* file,
                  uint32_t line,
                  TraceIdHierarchy ids);

 protected:
  // Set the result.
  void SetTraceResult(Error::Code error) override { result_ = error; }

  // Timestamp for when the object was created.
  Clock::time_point start_time_;

  // Result of this operation.
  Error::Code result_;

  // Name of this operation.
  const char* name_;

  // Name of the file.
  const char* file_name_;

  // Line number the log was generated from.
  uint32_t line_number_;

  // Category of this trace log.
  TraceCategory::Value category_;

 private:
  OSP_DISALLOW_COPY_AND_ASSIGN(TraceLoggerBase);
};

class SynchronousTraceLogger : public TraceLoggerBase {
 public:
  using TraceLoggerBase::TraceLoggerBase;

  ~SynchronousTraceLogger() override;

 private:
  OSP_DISALLOW_COPY_AND_ASSIGN(SynchronousTraceLogger);
};

class AsynchronousTraceLogger : public TraceLoggerBase {
 public:
  using TraceLoggerBase::TraceLoggerBase;

  ~AsynchronousTraceLogger() override;

 private:
  OSP_DISALLOW_COPY_AND_ASSIGN(AsynchronousTraceLogger);
};

// Inserts a fake element into the ScopedTraceOperation stack to set
// the current TraceId Hierarchy manually.
class TraceIdSetter final : public ScopedTraceOperation {
 public:
  explicit TraceIdSetter(TraceIdHierarchy ids)
      : ScopedTraceOperation(ids.current, ids.parent, ids.root) {}
  ~TraceIdSetter() final;

  // Creates a new TraceIdSetter to set the full TraceId Hierarchy to default
  // values and does not push it to the traces stack.
  static TraceIdSetter* CreateStackRootNode();

 private:
  // Implement abstract method for use in Macros.
  void SetTraceResult(Error::Code error) {}

  OSP_DISALLOW_COPY_AND_ASSIGN(TraceIdSetter);
};

// This helper object allows us to delete objects allocated on the stack in a
// unique_ptr.
template <class T>
class TraceInstanceHelper {
 private:
  class TraceOperationOnStackDeleter {
   public:
    void operator()(T* ptr) { ptr->~T(); }
  };

  using TraceInstanceWrapper = std::unique_ptr<T, TraceOperationOnStackDeleter>;

 public:
  template <typename... Args>
  static TraceInstanceWrapper Create(uint8_t storage[sizeof(T)], Args... args) {
    return TraceInstanceWrapper(new (storage) T(std::forward<Args&&>(args)...));
  }

  static TraceInstanceWrapper Empty() { return TraceInstanceWrapper(); }
};

}  // namespace internal
}  // namespace openscreen

#endif  // defined(ENABLE_TRACE_LOGGING)

#endif  // UTIL_TRACE_LOGGING_SCOPED_TRACE_OPERATIONS_H_
