// 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