// Copyright 2020 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//==============================================================================
//
// This file provides the interface for working with the tokenized trace
// backend.

#pragma once

#include <stdbool.h>
#include <stdint.h>
#include <string.h>

#ifndef PW_TRACE_GET_TIME_DELTA
#ifdef __cplusplus
#include <type_traits>
#endif  // __cplusplus
#endif  // PW_TRACE_GET_TIME_DELTA

#include "pw_status/status.h"
#include "pw_tokenizer/tokenize.h"
#include "pw_trace_tokenized/config.h"
#include "pw_trace_tokenized/internal/trace_tokenized_internal.h"

#ifdef __cplusplus
namespace pw {
namespace trace {

using EventType = pw_trace_EventType;

namespace internal {

// Simple ring buffer which is suitable for use in a critical section.
template <size_t kSize>
class TraceQueue {
 public:
  struct QueueEventBlock {
    uint32_t trace_token;
    EventType event_type;
    const char* module;
    uint32_t trace_id;
    uint8_t flags;
    size_t data_size;
    std::byte data_buffer[PW_TRACE_BUFFER_MAX_DATA_SIZE_BYTES];
  };

  pw::Status TryPushBack(uint32_t trace_token,
                         EventType event_type,
                         const char* module,
                         uint32_t trace_id,
                         uint8_t flags,
                         const void* data_buffer,
                         size_t data_size) {
    if (IsFull()) {
      return pw::Status::ResourceExhausted();
    }
    if (data_size > PW_TRACE_BUFFER_MAX_DATA_SIZE_BYTES) {
      return pw::Status::InvalidArgument();
    }
    event_queue_[head_].trace_token = trace_token;
    event_queue_[head_].event_type = event_type;
    event_queue_[head_].module = module;
    event_queue_[head_].trace_id = trace_id;
    event_queue_[head_].flags = flags;
    event_queue_[head_].data_size = data_size;
    for (size_t i = 0; i < data_size; i++) {
      event_queue_[head_].data_buffer[i] =
          reinterpret_cast<const std::byte*>(data_buffer)[i];
    }
    head_ = (head_ + 1) % kSize;
    is_empty_ = false;
    return pw::OkStatus();
  }

  const volatile QueueEventBlock* PeekFront() const {
    if (IsEmpty()) {
      return nullptr;
    }
    return &event_queue_[tail_];
  }

  void PopFront() {
    if (!IsEmpty()) {
      tail_ = (tail_ + 1) % kSize;
      is_empty_ = (tail_ == head_);
    }
  }

  void Clear() {
    head_ = 0;
    tail_ = 0;
    is_empty_ = true;
  }

  bool IsEmpty() const { return is_empty_; }
  bool IsFull() const { return !is_empty_ && (head_ == tail_); }

 private:
  std::array<volatile QueueEventBlock, kSize> event_queue_;
  volatile size_t head_ = 0;  // Next write
  volatile size_t tail_ = 0;  // Next read
  volatile bool is_empty_ =
      true;  // Used to distinquish if head==tail is empty or full
};

}  // namespace internal

class TokenizedTraceImpl {
 public:
  void Enable(bool enable) {
    if (enable != enabled_ && enable) {
      event_queue_.Clear();
    }
    enabled_ = enable;
  }
  bool IsEnabled() const { return enabled_; }

  void HandleTraceEvent(uint32_t trace_token,
                        EventType event_type,
                        const char* module,
                        uint32_t trace_id,
                        uint8_t flags,
                        const void* data_buffer,
                        size_t data_size);

 private:
  using TraceQueue = internal::TraceQueue<PW_TRACE_QUEUE_SIZE_EVENTS>;
  PW_TRACE_TIME_TYPE last_trace_time_ = 0;
  bool enabled_ = false;
  TraceQueue event_queue_;

  void HandleNextItemInQueue(
      const volatile TraceQueue::QueueEventBlock* event_block);
};

// A singleton object of the TokenizedTraceImpl class which can be used to
// interface with trace using the C++ API.
// Example: pw::trace::TokenizedTrace::Instance().Enable(true);
class TokenizedTrace {
 public:
  static TokenizedTraceImpl& Instance() { return instance_; };

 private:
  static TokenizedTraceImpl instance_;
};

}  // namespace trace
}  // namespace pw
#endif  // __cplusplus

// PW_TRACE_SET_ENABLED is used to enable or disable tracing.
#define PW_TRACE_SET_ENABLED(enabled) pw_trace_Enable(enabled)

// PW_TRACE_REF provides the uint32_t token value for a specific trace event.
// this can be used in the callback to perform specific actions for that trace.
// All the fields must match exactly to generate the correct trace reference.
// If the trace does not have a group, use PW_TRACE_GROUP_LABEL_DEFAULT.
//
// For example this can be used to skip a specific trace:
//   pw_trace_TraceEventReturnFlags TraceEventCallback(
//       uint32_t trace_ref,
//       pw_trace_EventType event_type,
//       const char* module,
//       uint32_t trace_id,
//       uint8_t flags) {
//     auto skip_trace_ref = PW_TRACE_REF(PW_TRACE_TYPE_INSTANT,
//                                        "test_module",    // Module
//                                        "test_label",     // Label
//                                        PW_TRACE_FLAGS_DEFAULT,
//                                        PW_TRACE_GROUP_LABEL_DEFAULT);
//     if (trace_ref == skip_trace_ref) {
//       return PW_TRACE_EVENT_RETURN_FLAGS_SKIP_EVENT;
//     }
//     return 0;
//   }
//
// The above trace ref would provide the tokenize value for the string:
//     "1|0|test_module||test_label"
//
// Another example:
//    #define PW_TRACE_MODULE test_module
//    PW_TRACE_INSTANT_DATA_FLAG(2, "label", "group", id, "%d", 5, 1);
// Would internally generate a token value for the string:
//    "1|2|test_module|group|label|%d"
// The trace_id, and data value are runtime values and not included in the
// token string.
#define PW_TRACE_REF(event_type, module, label, flags, group)          \
  PW_TOKENIZE_STRING_DOMAIN("trace",                                   \
                            PW_STRINGIFY(event_type) "|" PW_STRINGIFY( \
                                flags) "|" module "|" group "|" label)

#define PW_TRACE_REF_DATA(event_type, module, label, flags, group, type)    \
  PW_TOKENIZE_STRING_DOMAIN(                                                \
      "trace",                                                              \
      PW_STRINGIFY(event_type) "|" PW_STRINGIFY(flags) "|" module "|" group \
                                                       "|" label "|" type)
