#ifndef MISSION_DEVICES_GPSHYPERIONHANDLER_H_
#define MISSION_DEVICES_GPSHYPERIONHANDLER_H_

#include "fsfw/FSFW.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "devicedefinitions/GPSDefinitions.h"
#include "lwgps/lwgps.h"

/**
 * @brief   Device handler for the Hyperion HT-GPS200 device
 * @details
 * Flight manual:
 * https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/Hyperion_HT-GPS200
 */
class GPSHyperionHandler: public DeviceHandlerBase {
public:

	GPSHyperionHandler(object_id_t objectId, object_id_t deviceCommunication,
	        CookieIF* comCookie, bool debugHyperionGps = false);
	virtual ~GPSHyperionHandler();

    using gpioResetFunction_t = ReturnValue_t (*) (void* args);

	void setResetPinTriggerFunction(gpioResetFunction_t resetCallback, void*args);
	ReturnValue_t acceptExternalDeviceCommands() override;

	ReturnValue_t initialize() override;
protected:

	gpioResetFunction_t resetCallback = nullptr;
	void* resetCallbackArgs = nullptr;

	enum class InternalStates {
	    NONE,
	    WAIT_FIRST_MESSAGE,
	    IDLE
	};
	InternalStates internalState = InternalStates::NONE;
	bool commandExecuted = false;

	/* DeviceHandlerBase overrides */
	ReturnValue_t buildTransitionDeviceCommand(
	        DeviceCommandId_t *id) override;
	void doStartUp() override;
	void doShutDown() override;
	ReturnValue_t buildNormalDeviceCommand(
	        DeviceCommandId_t *id) override;
	ReturnValue_t buildCommandFromCommand(
	        DeviceCommandId_t deviceCommand, const uint8_t *commandData,
			size_t commandDataLen) override;
	ReturnValue_t scanForReply(const uint8_t *start, size_t len,
			DeviceCommandId_t *foundId, size_t *foundLen) override;
	ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
	        const uint8_t *packet) override;

	void fillCommandAndReplyMap() override;
	void modeChanged() override;
	uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
	ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
			LocalDataPoolManager &poolManager) override;
    virtual void debugInterface(uint8_t positionTracker = 0,
            object_id_t objectId = 0, uint32_t parameter = 0) override;
private:
	lwgps_t gpsData = {};
	GpsPrimaryDataset gpsSet;
	bool debugHyperionGps = false;
};

#endif /* MISSION_DEVICES_GPSHYPERIONHANDLER_H_ */