#include <stddef.h>
#include <cstring>
#include <iostream>

#include "UARTSpy.hpp"

UARTSpy::UARTSpy()
{
	ClearBuffers();
}

void UARTSpy::transmit(const uint8_t transmit_buffer[], size_t transmit_size)
{
	// dont overflow
	if(transmit_size < HIDDEN_BUFFER_SIZE)
	{
		memcpy(_xmitBuffer.buf, transmit_buffer, transmit_size);
		_xmitBuffer.bytes = transmit_size;
	}
	else
	{
		std::cout << "Too many bytes for UARTSpy" << std::endl;
	}
}

void UARTSpy::transmit(const std::string_view to_send)
{
	this->transmit(reinterpret_cast<const uint8_t*>(to_send.data()), to_send.size());
}

void UARTSpy::receive(uint8_t receive_buffer[], size_t receive_size, const UART::cb_t& rx_callback,
					  std::chrono::milliseconds receive_timeout_ms)
{
	rx_callback(status::OK);
	IGNORE_UNUSED(receive_timeout_ms);

	size_t toCopy = std::min(receive_size, _rcvBuffer.bytes);
	memcpy(receive_buffer, _rcvBuffer.buf, toCopy);
}

size_t UARTSpy::TransmittedBytes(uint8_t buf[], size_t buf_size)
{
	size_t toCopy = std::min(buf_size, _xmitBuffer.bytes);
	memcpy(buf, _xmitBuffer.buf, toCopy);

	return toCopy;
}

void UARTSpy::PutBytesInRcvBuf(const uint8_t buf[], size_t buf_bytes)
{
	if(buf_bytes < HIDDEN_BUFFER_SIZE)
	{
		memcpy(_rcvBuffer.buf, buf, buf_bytes);
		_rcvBuffer.bytes = buf_bytes;
	}
	else
	{
		std::cout << "Too many bytes for UARTSpy" << std::endl;
	}
}

void UARTSpy::ClearBuffers()
{
	memset(_xmitBuffer.buf, 0, sizeof(_xmitBuffer.buf));
	_xmitBuffer.bytes = 0;

	memset(_rcvBuffer.buf, 0, sizeof(_rcvBuffer.buf));
	_rcvBuffer.bytes = 0;
}