#pragma once
#include <vector>
#include <cstdint>
#include <climits>
#include <chrono>
class ChannelInterface
{
public:
enum Result
{
Success,
Error, // Connection closed
DataUnavailable,
InsufficientCapacity
};
// No socket handle exposed, so assumes that n+1 where n is this socket fd, and the appropriate fd_sets
// have the fd set in them according to the read/write/except flags.
virtual int Select(bool a_read, bool a_write, bool a_except = false, std::chrono::milliseconds a_timeout = std::chrono::milliseconds(0)) = 0;
// If a_readSize is -1, reads at most the size of the a_recvBuffer
// Returns the number of bytes that were read, or 0 for connection closed, or negative values for error
virtual int Read(std::vector<uint8_t>& a_recvBuffer, int a_readSize = INT_MAX) = 0;
// If a_writeSize is -1, sends up to the size of a_sendBuffer
// Returns the number of bytes that were written, or 0 for connection closed, or negative values for error
virtual int Write(const std::vector<uint8_t>& a_sendBuffer, int a_writeSize = INT_MAX) = 0;
// If data available (calls select first), reads data after size and up to the capacity of the a_recvBuffer and resizes the buffer accordingly
virtual Result SelectAndRead(std::vector<uint8_t>& a_recvBuffer, std::chrono::milliseconds a_timeout = std::chrono::milliseconds(0)) = 0;
// If able to write data (calls select first), writes data after a_offset and up to the size of the a_sendBuffer and updates a_offset accordingly
virtual Result SelectAndWrite(const std::vector<uint8_t>& a_sendBuffer, int& a_offset, std::chrono::milliseconds a_timeout = std::chrono::milliseconds(0)) = 0;
// Close the connection
virtual void Close() = 0;
// Get connected state
virtual bool IsConnected() = 0;
// Aliases for read/write
int Send(const std::vector<uint8_t>& a_sendBuffer, int a_writeSize = INT_MAX) { return Write(a_sendBuffer, a_writeSize); }
int Recv(std::vector<uint8_t>& a_recvBuffer, int a_readSize = INT_MAX) { return Read(a_recvBuffer, a_readSize); }
};