#pragma once

#include <stm32f4xx_hal.h>

#include <cstring>
//TODO should these be in CPFcpp.hpp?
#include "FIFO.hpp"
#include "SDLogger.hpp"

//TODO Need to deal with some ports being UARTs and some being USARTs
static UART_HandleTypeDef hUART7 = UART_HandleTypeDef();
static DMA_HandleTypeDef hDMA_RX = DMA_HandleTypeDef();
static DMA_HandleTypeDef hDMA_TX = DMA_HandleTypeDef();

static uint8_t uart7RXBuffer[256];

//TODO probably should make this inheritable by future uartUBloxGPS and i2cUBloxGPS
class ubloxGPS
{
public:
	static ubloxGPS& getInstance(USART_TypeDef* uartNumber, char const* id)
	{
		static ubloxGPS instance(uartNumber, id);
		cout << "\t\tpublic ubloxGPS& getInstance" << endl;
		return instance;
	}

private:
	ubloxGPS(USART_TypeDef* uartNumber, char const* id)
	{
		configUART7();
		defineCommands();
		IDTag = id;
		cout << "\t\tubloxGPS constructor, qID: " << IDTag << endl;
	}

public:
	enum GPSCommands
	{
		getPos = 0,
		getTime,
	};
	
	int8_t sendCommand(GPSCommands command, string &returnTimestamp, string &returnMsgString);

protected:

private:
	SDLogger sdLogger = SDLogger::getInstance();

	struct CommandParams
	{
		uint8_t*  cmdPtr;
		uint16_t cmdSize;
		uint16_t responseSize;
		uint32_t cmdTimeout;
		char cmdLabel[16] = "";
		string correctResponse = "";
		
	};
	
	struct CommandParams CmdParam[2];
	void defineCommands()
	{
		//TODO figure out how to make these const
		CmdParam[getPos].cmdPtr = (uint8_t *)"$PUBX,00*33\r\n";
		CmdParam[getPos].cmdSize = sizeof("$PUBX,00*33\r\n");
		CmdParam[getPos].responseSize = 108;
		CmdParam[getPos].cmdTimeout = 1000;
		strcpy(CmdParam[getPos].cmdLabel, "Get position");
		CmdParam[getPos].correctResponse = "$PUBX,00";

		CmdParam[getTime].cmdPtr = (uint8_t *)"$PUBX,04*37\r\n";
		CmdParam[getTime].cmdSize = sizeof("$PUBX,04*37\r\n");
		CmdParam[getTime].responseSize = 66;
		CmdParam[getTime].cmdTimeout = 1000;
		strcpy(CmdParam[getTime].cmdLabel, "Get time");
		CmdParam[getTime].correctResponse = "$PUBX,04";
	}
	
	void configUART7();
	int8_t checkRespAndTimeout(string &actualResponse, string &correctResponse);
	int8_t checkTimeout(bool clearCount);
	int8_t checkResponse();
	CommandParams setCmdParams(ubloxGPS::GPSCommands cmd);
	
	char const* IDTag;
	int8_t numTimeouts = 0;
};
