// 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::RESOURCE_EXHAUSTED;
    }
    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::Status::OK;
  }

  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)
