#ifndef MISSION_DEVICES_SUSHANDLER_H_
#define MISSION_DEVICES_SUSHANDLER_H_

#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>

#include "devicedefinitions/SusDefinitions.h"

/**
 * @brief	This is the device handler class for the SUS sensor. The sensor is
 *          based on the MAX1227 ADC. Details about the SUS electronic can be found at
 *          https://egit.irs.uni-stuttgart.de/eive/eive_dokumente/src/branch/master/400_Raumsegment/443_SunSensorDocumentation/release
 *
 * @details Datasheet of MAX1227: https://datasheets.maximintegrated.com/en/ds/MAX1227-MAX1231.pdf
 *
 * @note    When adding a SusHandler to the polling sequence table make sure to add a slot with
 *          the executionStep FIRST_WRITE. Otherwise the communication sequence will never be
 *          started.
 *
 * @author	J. Meier
 */
class SusHandler : public DeviceHandlerBase {
 public:
  static const uint8_t FIRST_WRITE = 7;

  SusHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
             LinuxLibgpioIF* gpioComIF, gpioId_t chipSelectId);
  virtual ~SusHandler();

  virtual ReturnValue_t performOperation(uint8_t counter) override;

  virtual ReturnValue_t initialize() override;

 protected:
  void doStartUp() override;
  void doShutDown() override;
  ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
  ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
  void fillCommandAndReplyMap() override;
  ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
                                        size_t commandDataLen) override;
  ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId,
                             size_t* foundLen) override;
  ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
  void setNormalDatapoolEntriesInvalid() override;
  uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
  ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
                                        LocalDataPoolManager& poolManager) override;

 private:
  static const uint8_t INTERFACE_ID = CLASS_ID::SUS_HANDLER;

  static const ReturnValue_t ERROR_UNLOCK_MUTEX = MAKE_RETURN_CODE(0xA0);
  static const ReturnValue_t ERROR_LOCK_MUTEX = MAKE_RETURN_CODE(0xA1);

  enum class CommunicationStep { IDLE, WRITE_SETUP, START_CONVERSIONS, READ_CONVERSIONS };

  LinuxLibgpioIF* gpioComIF = nullptr;

  gpioId_t chipSelectId = gpio::NO_GPIO;

  SUS::SusDataset dataset;

  uint8_t cmdBuffer[SUS::MAX_CMD_SIZE];
  CommunicationStep communicationStep = CommunicationStep::IDLE;

  MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
  uint32_t timeoutMs = 20;

  MutexIF* spiMutex = nullptr;
};

#endif /* MISSION_DEVICES_SUSHANDLER_H_ */