// 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();
    }
    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)
