// 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.
//==============================================================================
//
// The file provides the API for working with callbacks and sinks for the
// tokenized trace module.

#pragma once

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

#include <span>

#include "pw_status/status.h"
#include "pw_trace_tokenized/trace_tokenized.h"

// Config options
// PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS is the maximum number of event callbacks
// which can be registered at a time.
#ifndef PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS
#define PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS 2
#endif  // PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS

// PW_TRACE_CONFIG_MAX_SINKS is the maximum number of encoded event sinks which
// can be registered at a time.
#ifndef PW_TRACE_CONFIG_MAX_SINKS
#define PW_TRACE_CONFIG_MAX_SINKS 2
#endif  // PW_TRACE_CONFIG_MAX_SINKS

PW_EXTERN_C_START
// The pw_trace_EventCallback is called before the sample is encoded or sent
// to the sinks. Bits in the return argument can be set to change the behaviour
// of tracing.
//    - PW_TRACE_EVENT_RETURN_FLAGS_SKIP_EVENT can optionally be set true to
//    skip this sample.
//    - PW_TRACE_EVENT_RETURN_FLAGS_DISABLE_AFTER_PROCESSING can be set true to
//      disable tracing after this sample.
//
// When registering the callback the parameter 'called_on_every_event' is used
// to indicate if the callback should be called even when tracing is disabled.
// This behaviour is useful to implment a tracing behaviour, where tracing can
// turn on when a specific event occurs.
//
// If a handle pointer is provided it will be set to a value, which can be later
// used to unregister the callback.
//
// The user_data pointer is provider for use by the application, it can be used
// to allow a single function callback to be registered multiple times but act
// differently by providing it with different context objects as pointers.
//
// NOTE: Since callbacks are called within the trace event lock, they should not
// register/unregister sinks or callbacks or trigger other trace events.
typedef enum {
  PW_TRACE_CALL_ONLY_WHEN_ENABLED = 0,
  PW_TRACE_CALL_ON_EVERY_EVENT = 1,
} pw_trace_ShouldCallOnEveryEvent;

enum {
  PW_TRACE_EVENT_RETURN_FLAGS_NONE = 0,
  PW_TRACE_EVENT_RETURN_FLAGS_SKIP_EVENT = 1 << 0,
  PW_TRACE_EVENT_RETURN_FLAGS_DISABLE_AFTER_PROCESSING = 1 << 1
};
typedef uint32_t pw_trace_TraceEventReturnFlags;

typedef size_t pw_trace_EventCallbackHandle;
typedef pw_trace_TraceEventReturnFlags (*pw_trace_EventCallback)(
    void* user_data,
    uint32_t trace_ref,
    pw_trace_EventType event_type,
    const char* module,
    uint32_t trace_id,
    uint8_t flags);

pw_Status pw_trace_RegisterEventCallback(
    pw_trace_EventCallback callback,
    pw_trace_ShouldCallOnEveryEvent called_on_every_event,
    void* user_data,
    pw_trace_EventCallbackHandle* handle);

// pw_trace_UnregisterEventCallback will cause the callback to not receive any
// more events.
pw_Status pw_trace_UnregisterEventCallback(pw_trace_EventCallbackHandle handle);

// pw_trace_Sink* is called after the trace event is encoded.
// Trace will internally handle locking, so every Start event will have a
// matching End event before another sequence is started.
// The number of bytes sent to AddBytes will be the number provided at the
// start, allowing buffers to allocate the required amount at the start when
// necessary.
//
// If Status::Ok() is not returned from Start, the events bytes will be skipped.
//
// NOTE: Called while tracing is locked (which might be a critical section
// depending on application), so quick/simple operations only. One trace event
// might result in multiple callbacks if the data is split up.
//
// If a handle pointer is provided it will be set to a value, which can be later
// used to unregister the callback.
//
// The user_data pointer is provider for use by the application, it can be used
// to allow a single function callback to be registered multiple times but act
// differently by providing it with different user_data values.
//
// NOTE: Since callbacks are called within the trace event lock, they should not
// register/unregister sinks or callbacks or trigger other trace events.
typedef void (*pw_trace_SinkStartBlock)(void* user_data, size_t size);
typedef void (*pw_trace_SinkAddBytes)(void* user_data,
                                      const void* bytes,
                                      size_t size);
typedef void (*pw_trace_SinkEndBlock)(void* user_data);
typedef size_t pw_trace_SinkHandle;
pw_Status pw_trace_RegisterSink(pw_trace_SinkStartBlock start_func,
                                pw_trace_SinkAddBytes add_bytes_func,
                                pw_trace_SinkEndBlock end_block_func,
                                void* user_data,
                                pw_trace_SinkHandle* handle);

// pw_trace_UnregisterSink will cause the sink to stop receiving trace data.
pw_Status pw_trace_UnregisterSink(pw_trace_SinkHandle handle);

PW_EXTERN_C_END

#ifdef __cplusplus
namespace pw {
namespace trace {

class CallbacksImpl {
 public:
  enum CallOnEveryEvent {
    kCallOnlyWhenEnabled = PW_TRACE_CALL_ONLY_WHEN_ENABLED,
    kCallOnEveryEvent = PW_TRACE_CALL_ON_EVERY_EVENT,
  };
  using SinkStartBlock = pw_trace_SinkStartBlock;
  using SinkAddBytes = pw_trace_SinkAddBytes;
  using SinkEndBlock = pw_trace_SinkEndBlock;
  using SinkHandle = pw_trace_SinkHandle;
  struct SinkCallbacks {
    void* user_data;
    SinkStartBlock start_block;
    SinkAddBytes add_bytes;
    SinkEndBlock end_block;
  };
  using EventCallback = pw_trace_EventCallback;
  using EventCallbackHandle = pw_trace_EventCallbackHandle;
  struct EventCallbacks {
    void* user_data;
    EventCallback callback;
    CallOnEveryEvent called_on_every_event;
  };

  pw::Status RegisterSink(SinkStartBlock start_func,
                          SinkAddBytes add_bytes_func,
                          SinkEndBlock end_block_func,
                          void* user_data = nullptr,
                          SinkHandle* handle = nullptr);
  pw::Status UnregisterSink(SinkHandle handle);
  pw::Status UnregisterAllSinks();
  SinkCallbacks* GetSink(SinkHandle handle);
  void CallSinks(std::span<const std::byte> header,
                 std::span<const std::byte> data);

  pw::Status RegisterEventCallback(
      EventCallback callback,
      CallOnEveryEvent called_on_every_event = kCallOnlyWhenEnabled,
      void* user_data = nullptr,
      EventCallbackHandle* handle = nullptr);
  pw::Status UnregisterEventCallback(EventCallbackHandle handle);
  pw::Status UnregisterAllEventCallbacks();
  EventCallbacks* GetEventCallback(EventCallbackHandle handle);
  pw_trace_TraceEventReturnFlags CallEventCallbacks(
      CallOnEveryEvent called_on_every_event,
      uint32_t trace_ref,
      EventType event_type,
      const char* module,
      uint32_t trace_id,
      uint8_t flags);
  size_t GetCalledOnEveryEventCount() const {
    return called_on_every_event_count_;
  }

 private:
  EventCallbacks event_callbacks_[PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS];
  SinkCallbacks sink_callbacks_[PW_TRACE_CONFIG_MAX_SINKS];
  size_t called_on_every_event_count_ = 0;

  bool IsSinkFree(pw_trace_SinkHandle handle) {
    return sink_callbacks_[handle].start_block == nullptr &&
           sink_callbacks_[handle].add_bytes == nullptr &&
           sink_callbacks_[handle].end_block == nullptr;
  }
};

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

 private:
  static CallbacksImpl instance_;
};

// This is a convenience class to register the callback when the object is
// created. For example if the callback should always be registered this can be
// created as a global object to avoid needing to call register directly.
class RegisterCallbackWhenCreated {
 public:
  RegisterCallbackWhenCreated(
      CallbacksImpl::EventCallback event_callback,
      CallbacksImpl::CallOnEveryEvent called_on_every_event =
          CallbacksImpl::kCallOnlyWhenEnabled,
      void* user_data = nullptr) {
    Callbacks::Instance().RegisterEventCallback(
        event_callback, called_on_every_event, user_data);
  }
  RegisterCallbackWhenCreated(CallbacksImpl::SinkStartBlock sink_start,
                              CallbacksImpl::SinkAddBytes sink_add_bytes,
                              CallbacksImpl::SinkEndBlock sink_end,
                              void* user_data = nullptr) {
    Callbacks::Instance().RegisterSink(
        sink_start, sink_add_bytes, sink_end, user_data);
  }
};

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