#ifndef MISSION_SYSTEM_COMSUBSYSTEM_H_
#define MISSION_SYSTEM_COMSUBSYSTEM_H_

#include <common/config/eive/eventSubsystemIds.h>
#include <fsfw/events/EventMessage.h>
#include <fsfw/parameters/HasParametersIF.h>
#include <fsfw/parameters/ParameterHelper.h>
#include <fsfw/subsystem/Subsystem.h>

#include "mission/com/defs.h"

class ComSubsystem : public Subsystem, public ReceivesParameterMessagesIF {
 public:
  static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::COM_SUBSYSTEM;

  //! [EXPORT] : [COMMENT] The transmit timer to protect the Syrlinks expired
  //! P1: The current timer value
  static const Event TX_TIMER_EXPIRED = MAKE_EVENT(1, severity::INFO);
  //! [EXPORT] : [COMMENT] Transmitter will be turned on due to detection of bitlock
  static const Event BIT_LOCK_TX_ON = MAKE_EVENT(2, severity::INFO);

  /**
   * @brief Constructor
   *
   * @param setObjectId
   * @param maxNumberOfSequences
   * @param maxNumberOfTables
   * @param transmitterTimeout	Maximum time the transmitter of the syrlinks
   * 														will
   * be enabled
   */
  ComSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables,
               uint32_t transmitterTimeout);
  virtual ~ComSubsystem() = default;

  MessageQueueId_t getCommandQueue() const override;
  ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
                             ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
                             uint16_t startAtIndex) override;
  virtual void performChildOperation() override;

 private:
  static const Mode_t INITIAL_MODE = 0;

  ReturnValue_t handleCommandMessage(CommandMessage *message) override;

  ReturnValue_t initialize() override;

  void startTransition(Mode_t mode, Submode_t submode) override;
  void announceMode(bool recursive) override;

  void readEventQueue();
  void handleEventMessage(EventMessage *eventMessage);
  void handleBitLockEvent();
  void handleCarrierLockEvent();
  void checkTransmitterCountdown();
  /**
   * @brief	Enables transmitter in low rate mode
   */
  void startRxAndTxLowRateSeq();
  void startRxOnlyRecovery(bool forced);

  /**
   * @brief	Returns true if mode is a mode where the transmitter is on
   */
  bool isTxMode(Mode_t mode);

  uint8_t datarateCfg = static_cast<uint8_t>(com::Datarate::LOW_RATE_MODULATION_BPSK);

  // Maximum time after which the transmitter will be turned of. This is a
  // protection mechanism due prevent the syrlinks from overheating
  uint32_t transmitterTimeout = 0;
  ParameterHelper paramHelper;

  MessageQueueIF *eventQueue = nullptr;

  bool enableTxWhenCarrierLock = false;
  bool performRecoveryToRxOnly = false;

  // Countdown will be started as soon as the transmitter was enabled
  Countdown transmitterCountdown;

  // Transmitter countdown only active when sysrlinks transmitter is on (modes:
  // rx and tx low rate, rx and tx high rate, rx and tx default rate)
  bool countdownActive = false;

  // True when bit lock occurred while COM subsystem is in a transition. This
  // variable is used to remember the bit lock and execute the default rate
  // sequence after the active transition has been completed
  bool rememberBitLock = false;
};

#endif /* MISSION_SYSTEM_COMSUBSYSTEM_H_ */