#ifndef _TcpEntity_H_
#define _TcpEntity_H_

#include <Winsock2.h>
#include <string>
#include <vector>
#include <thread>
#include <functional>

#include "CommEntity.h"

using namespace std;

enum class ETcpType
{
	SERVER = 0,
	CLIENT = 1,
};

enum class ETcpEvent
{
	NUL = 0,		//
	SRV_SUCCESS,	// 服务端启动成功(listen成功)
	ACCEPT,			// 服务端接收到客户端的连接
	CONN_OK,		// 作为客户端时，连接成功
	CONN_ERR,		// 作为客户端时，连接失败
	MSG_RECV,		// 接收消息
	MSG_SEND,		// 发送消息
	CLOSE,			// 断开连接
	ERR				// 异常错误
};

class TcpHandler;
class TcpParser;

class TcpEntity : public CommEntity, public std::enable_shared_from_this<TcpEntity>
{
public:
	struct Client
	{
		std::string clientId;
		SOCKET sock;
		SOCKADDR_IN sockaddr;
		std::string host;
	};

public:
	TcpEntity();
	~TcpEntity();

	int start() override;

	void setAddr(string host, int port, int commtype);
	std::string getAddr() { return addr; }
	std::string getAddrPort() { return addr + ":" + std::to_string(port); }
	int getPort() { return port; }

	void  setReconnect(int ms);
	bool write(std::string data);

private:
	void runServerLoop();
	void runServerRecvLoop(Client client, std::string client_name);
	void runClientLoop();

private:
	// 本机的SOCKET对象
	SOCKET sock = INVALID_SOCKET;

	// socket addr信息
	SOCKADDR_IN sockaddr {};

	// 通讯地址，作为客户端时有效
	std::string addr;

	// 通讯端口
	int port = 0;

	// 重连间隔时间，单位秒
	int tReconnect_ = 0;

	// 作为服务端时连接的客户端SOCKET
	std::vector<Client> vecClient;

	// 状态更新时间戳
	int64_t ts_ = 0; 

	int64_t tsHeartbeat_ = 0;
};

class TcpHandler
{
public:
	virtual void onEvent(TcpEntity* entity, TcpEntity::Client* client, ETcpEvent evt, std::string msg) {};
};

#endif // !_TcpEntity_H_