#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/memory/SdCardMountedIF.h>
#include <mission/tmtc/PusLiveDemux.h>

#include <atomic>
#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, SdCardMountedIF& sdcMan,
              const char* sequenceCounterFilename, std::atomic_bool& saveSequenceCount)
        : objectId(objId),
          name(name),
          tmStore(tmStore),
          ipcStore(ipcStore),
          tmMsgDepth(tmMsgDepth),
          sdcMan(sdcMan),
          sequenceCounterFilename(sequenceCounterFilename),
          saveSequenceCount(saveSequenceCount) {}
    object_id_t objectId;
    const char* name;
    StorageManagerIF& tmStore;
    StorageManagerIF& ipcStore;
    uint32_t tmMsgDepth;
    SdCardMountedIF& sdcMan;
    const char* sequenceCounterFilename;
    std::atomic_bool& saveSequenceCount;
  };
  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);
  ReturnValue_t initialize() override;

  ReturnValue_t saveSequenceCountToFile();

  ~TmFunnelBase() override;

 protected:
  const char* name;
  StorageManagerIF& tmStore;
  StorageManagerIF& ipcStore;
  MessageQueueIF* tmQueue = nullptr;
  PusLiveDemux liveDemux;
  SdCardMountedIF& sdcMan;
  const char* sequenceCounterFilename;
  std::atomic_bool& saveSequenceCount;
  uint16_t sourceSequenceCount = 0;
};

#endif /* MISSION_TMTC_TMFUNNELBASE_H_ */