#ifndef MISSION_TMTC_LIVETMTASK_H_
#define MISSION_TMTC_LIVETMTASK_H_

#include <fsfw/modes/HasModesIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/subsystem/ModeTreeChildIF.h>
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/timemanager/Countdown.h>
#include <mission/com/VirtualChannelWithQueue.h>
#include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PusTmFunnel.h>

class LiveTmTask : public SystemObject,
                   public HasModesIF,
                   public ExecutableObjectIF,
                   public ModeTreeChildIF,
                   public ModeTreeConnectionIF {
 public:
  LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
             VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked);

  ReturnValue_t performOperation(uint8_t opCode) override;
  ReturnValue_t initialize() override;
  ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;

 private:
  MessageQueueIF* requestQueue;
  ModeHelper modeHelper;
  Mode_t mode = HasModesIF::MODE_OFF;
  Countdown tmFunnelCd = Countdown(100);
  PusTmFunnel& pusFunnel;
  CfdpTmFunnel& cfdpFunnel;
  VirtualChannelWithQueue& channel;
  uint32_t packetCounter = 0;
  const std::atomic_bool& ptmeLocked;

  void readCommandQueue(void);

  MessageQueueId_t getCommandQueue() const override;

  void getMode(Mode_t* mode, Submode_t* submode) override;

  ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
                                 uint32_t* msToReachTheMode) override;

  void startTransition(Mode_t mode, Submode_t submode) override;

  void announceMode(bool recursive) override;

  object_id_t getObjectId() const override;
  const HasHealthIF* getOptHealthIF() const override;
  const HasModesIF& getModeIF() const override;
  ModeTreeChildIF& getModeTreeChildIF() override;
};

#endif /* MISSION_TMTC_LIVETMTASK_H_ */