#ifndef A042D3CF_5927_42A2_93FF_E49E940B32BD
#define A042D3CF_5927_42A2_93FF_E49E940B32BD

#include <memory>
#include <regex>
#include <string>
#include <vector>

#include "mana_c_api.h"

namespace mesytec::mnode::mana
{

class IManaSink
{
  public:
    virtual ~IManaSink() = default;

    virtual void begin_run(const char *descriptor_json) = 0;
    virtual void end_run(const char *descriptor_json) = 0;
    virtual void process_event(uint16_t eventIndex, mana_offset_array_t *arrays, size_t arrayCount,
                               size_t totalBytes) = 0;

    virtual void process_system_event(const uint32_t *data, size_t size) = 0;

  protected:
    IManaSink() = default;

  private:
    IManaSink(const IManaSink &) = delete;
    IManaSink &operator=(const IManaSink &) = delete;
};

class IManaBufferSink
{
  public:
    virtual ~IManaBufferSink() = default;

    virtual void begin_run(const char *descriptor_json) = 0;
    virtual void end_run(const char *descriptor_json) = 0;
    // buffer is the same format as used in mana_nng.hpp. It starts with a MessageHeader::Eventdata
    // structure.
    virtual void process_event_buffer(const uint8_t *buffer, size_t size) = 0;
    virtual void process_system_event(const uint32_t *data, size_t size) = 0;

  protected:
    IManaBufferSink() = default;

  private:
    IManaBufferSink(const IManaBufferSink &) = delete;
    IManaBufferSink &operator=(const IManaBufferSink &) = delete;
};

class IManaPlugin
{
  public:
    virtual ~IManaPlugin() = default;
    virtual std::unique_ptr<IManaSink> makeSink() = 0;

  protected:
    IManaPlugin() = default;

  private:
    IManaPlugin(const IManaPlugin &) = delete;
    IManaPlugin &operator=(const IManaPlugin &) = delete;
};

} // namespace mesytec::mnode::mana

#define MANA_CPP_PLUGIN extern "C" mana::IManaPlugin *mana_get_plugin

#endif /* A042D3CF_5927_42A2_93FF_E49E940B32BD */
