#pragma once


#include "ChannelInterface.h"


class ClientChannel : public ChannelInterface
{
public:
  enum SocketValues { InvalidSocket = -1 };

  template <typename F, typename ...Ts>
  int FunctionWrapper(int errVal, F f, Ts ...args)
  {
    int ret = (m_serverSocket != InvalidSocket) ? f(args...) : errVal;
    m_serverSocket = (ret <= errVal) ? InvalidSocket : m_serverSocket;
    return ret;
  }

  ClientChannel(int a_serverSocket = InvalidSocket);

  int Select(bool a_read, bool a_write, bool a_except = false, std::chrono::milliseconds a_timeout = std::chrono::milliseconds(0)) override;
  int Read(std::vector<uint8_t>& a_recvBuffer, int a_readSize = -1) override;
  int Write(const std::vector<uint8_t>& a_sendBuffer, int a_writeSize = -1) override;

  Result SelectAndRead(std::vector<uint8_t>& a_recvBuffer, std::chrono::milliseconds a_timeout = std::chrono::milliseconds(0)) override;
  Result SelectAndWrite(const std::vector<uint8_t>& a_sendBuffer, int& a_offset, std::chrono::milliseconds a_timeout = std::chrono::milliseconds(0)) override;

  void Close() override;
  bool IsConnected() override;

private:
  int m_serverSocket = InvalidSocket; // socket from the client to the server
};

