#pragma once

#include <memory.h>
#include <etl/string.h>
#include <etl/queue.h>
#include <string>

// From https://www.techiedelight.com/queue-implementation-cpp/

class FIFO
{
  public:
	// TODO: answer here is templates
	FIFO(std::string qID) // TODO might want to pass struct to be queued in constructor instead of
						  // forcing it to be FIFORecord
	{
		head = 0;
		tail = 0;
		count = 0;
		capacity = 32;
		qName = qID;

		// etlTest();
	}

	// TODO: answer here is templates
	struct FIFORecord // TODO it would be better to figure out a way to set the queue width and
					  // depth through the constructor
	{
		uint64_t tickstamp;
		uint8_t message[256];
	};

	~FIFO() = default;

	bool dequeue(uint64_t& tickstamp, uint8_t deQBytes[]);
	bool enqueue(uint64_t tickstamp, uint8_t enQBytes[]);
	bool dequeue(FIFORecord& deQueueRecord);
	bool enqueue(FIFORecord enQueueRecord);

	int peek();
	uint32_t getCount();
	bool isEmpty();
	bool isFull();
	void clearRecord(FIFORecord& inRecord);

	uint32_t qWidth;

  protected:
	uint32_t capacity; // maximum capacity of the queue
	uint32_t head; // points to front element in the queue (if any)
	uint32_t tail; // points to last element in the queue
	uint32_t count; // current size of the queue
	std::string qName;

	FIFORecord fifoRecords[32];

  private:
	void etlTest();

	// Just to see how much memory a stl queue takes.
	// etl::queue<FIFORecord, 32, etl::memory_model::MEMORY_MODEL_SMALL> stlQ;
};
