#ifndef MISSION_DEVICES_STARTRACKERHANDLER_H_
#define MISSION_DEVICES_STARTRACKERHANDLER_H_

#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <mission/devices/devicedefinitions/StarTrackerDefinitions.h>
#include <thirdparty/arcsec_star_tracker/common/SLIP.h>

/**
 * @brief	This is the device handler for the star tracker from arcsec.
 *
 * @details Datasheet: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/
 *                     Arbeitsdaten/08_Used%20Components/ArcSec_KULeuven_Startracker/
 *                     Sagitta%201.0%20Datapack&fileid=659181
 *
 * @author	J. Meier
 */
class StarTrackerHandler: public DeviceHandlerBase {
public:

	/**
	 * @brief Constructor
	 *
	 * @param objectId
	 * @param comIF
	 * @param comCookie
	 * @param gpioComIF	Pointer to gpio communication interface
	 * @param enablePin 	GPIO connected to the enable pin of the reaction wheels. Must be pulled
	 * 						to high to enable the device.
	 */
	StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie);
	virtual ~StarTrackerHandler();

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;

	/**
	 * @brief   Overwritten here to always read all available data from the UartComIF.
	 */
	virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;

private:

	static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER;

	//! [EXPORT] : [COMMENT] Received reply is too short
    static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xB0);
	//! [EXPORT] : [COMMENT] Received reply with invalid CRC
    static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xB0);

    static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER;

    //! [EXPORT] : [COMMENT] Result code of tm reply indicates an error
    static const ReturnValue_t TM_REPLY_ERROR = MAKE_RETURN_CODE(0xA0);
    //! P1: TM id

    StarTracker::TemperatureSet temperatureSet;

	uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE];
	uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE];
	uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE];

	/** Size of buffer derived from the egse source code */
	uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2];

	slip_decode_state slipInfo;

	enum class InternalState {
	    TEMPERATURE_REQUEST
    };

	InternalState internalState = InternalState::TEMPERATURE_REQUEST;

	/**
	 * @brief   This function initializes the serial link ip protocol struct slipInfo.
	 */
	void slipInit();

	void prepareTemperatureRequest();

	/**
	 * @brief   This function handles the telemetry reply of a temperature request.
	 */
	void handleTemperatureTm();
};

#endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */