#ifndef MISSION_TMTC_TMFUNNELBASE_H_
#define MISSION_TMTC_TMFUNNELBASE_H_

#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/storagemanager/StorageManagerIF.h>
#include <fsfw/tmstorage/TmStoreFrontendSimpleIF.h>
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
#include <fsfw/tmtcservices/TmTcMessage.h>
#include <mission/tmtc/PusLiveDemux.h>

#include <vector>

class TmFunnelBase : public AcceptsTelemetryIF, public SystemObject {
 public:
  struct FunnelCfg {
    FunnelCfg(object_id_t objId, const char* name, StorageManagerIF& tmStore,
              StorageManagerIF& ipcStore, uint32_t tmMsgDepth)
        : objectId(objId),
          name(name),
          tmStore(tmStore),
          ipcStore(ipcStore),
          tmMsgDepth(tmMsgDepth) {}
    object_id_t objectId;
    const char* name;
    StorageManagerIF& tmStore;
    StorageManagerIF& ipcStore;
    uint32_t tmMsgDepth;
  };
  explicit TmFunnelBase(FunnelCfg cfg);
  [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
  void addLiveDestination(const char* name, const AcceptsTelemetryIF& downlinkDestination,
                          uint8_t vcid = 0);
  ReturnValue_t demultiplexLivePackets(store_address_t origStoreId, const uint8_t* tmData,
                                       size_t tmSize);

  ~TmFunnelBase() override;

 protected:
  const char* name;
  StorageManagerIF& tmStore;
  StorageManagerIF& ipcStore;
  MessageQueueIF* tmQueue = nullptr;
  PusLiveDemux liveDemux;
};

#endif /* MISSION_TMTC_TMFUNNELBASE_H_ */