#pragma once
#include <myapp/modbus/rawtcpserver.h>
#include "context.h"
#include <list>

namespace myapp::modbus {

class raw_tcp_server_impl
	: public raw_tcp_server
{
public:
	explicit raw_tcp_server_impl(std::shared_ptr<logging::logger> logger, context ctx);
	~raw_tcp_server_impl();

public:
	class socket
	{
	public:
		socket() = default;
		socket(int fd) : fd_(fd) { }
		~socket();

		friend void swap(socket&, socket&) noexcept;
		socket(socket&& o) noexcept;
		socket& operator=(socket&& o) noexcept;

		bool empty() const noexcept { return fd_ == -1; }
		operator int() const noexcept { return fd_; }
		operator int*() noexcept { return &fd_; }

		std::string const& peer_name();

	private:
		int fd_{ -1 };
		std::string peername_{};
	};

public:
	void listen(int backlog) override;
	void poll() override;
	void set_data_handler(data_handler_t) noexcept override;

private:
	void accept();
	void handle_data(socket&);

private:
	context ctx_;
	std::shared_ptr<logging::logger> logger_;
	socket listener_;
	std::list<socket> clients_;
	data_handler_t data_handler_;
};
	
} /* namespace myapp::modbus */
