#ifndef MISSION_DEVICES_SUSHANDLER_H_
#define MISSION_DEVICES_SUSHANDLER_H_

#include "devicedefinitions/SusDefinitions.h"
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
#include <fsfw/ipc/MutexGuard.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_ */