#ifndef MISSION_ARDUINOCOMMINTERFACE_H_
#define MISSION_ARDUINOCOMMINTERFACE_H_

#include <fsfw/container/FixedMap.h>
#include <fsfw/container/SimpleRingBuffer.h>
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/objectmanager/SystemObject.h>

#include <cstdint>
#include <map>

#ifdef WIN32
#include <windows.h>
#endif

//Forward declaration, so users don't peek
class ArduinoCookie;

class ArduinoComIF: public SystemObject,
		public DeviceCommunicationIF {
public:
	static const uint8_t MAX_NUMBER_OF_SPI_DEVICES = 8;
	static const uint8_t MAX_PACKET_SIZE = 64;

	static const uint8_t COMMAND_INVALID = -1;
	static const uint8_t COMMAND_SPI = 1;

	ArduinoComIF(object_id_t setObjectId, bool promptComIF = false,
	        const char *serialDevice = nullptr);
	void setBaudrate(uint32_t baudRate);

	virtual ~ArduinoComIF();

	/** DeviceCommunicationIF overrides */
    virtual ReturnValue_t initializeInterface(CookieIF * cookie) override;
    virtual ReturnValue_t sendMessage(CookieIF *cookie,
            const uint8_t * sendData, size_t sendLen) override;
    virtual ReturnValue_t getSendSuccess(CookieIF *cookie) override;
    virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie,
            size_t requestLen) override;
    virtual ReturnValue_t readReceivedMessage(CookieIF *cookie,
            uint8_t **buffer, size_t *size) override;

private:
#ifdef LINUX
#elif WIN32
    HANDLE hCom = INVALID_HANDLE_VALUE;
#endif
	// remembering if the initialization in the ctor worked
	// if not, all calls are disabled
	bool initialized = false;
	int serialPort = 0;
	// Default baud rate is 9600 for now.
	uint32_t baudRate = 9600;

	//used to know where to put the data if a reply is received
	std::map<uint8_t, ArduinoCookie> spiMap;

	SimpleRingBuffer rxBuffer;

	ReturnValue_t sendMessage(uint8_t command, uint8_t address,
			const uint8_t *data, size_t dataLen);
	void handleSerialPortRx();

	void handlePacket(uint8_t *packet, size_t packetLen);
};

#endif /* MISSION_ARDUINOCOMMINTERFACE_H_ */