#ifndef SERVER_HPP
# define SERVER_HPP

# include <string>
# include <vector>
# include <map>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <poll.h>
# include <fcntl.h>
# include <unistd.h>
# include "ParseBuffer.hpp"
# include <stdexcept>
# include <cstring>
# include <cerrno>
# include "CommandValidator.hpp"

struct ConnectedUser
{
	int				fd;
	std::string		nick;
	std::string		username;
	std::string		realname;
	std::string		hostname;
	bool			passOk;
	bool			nickOk;
	bool			userOk;
	ParseBuffer		parseBuffer;

	ConnectedUser(void);
	explicit ConnectedUser(int fd);
	bool	isRegistered(void) const;
};

class Server
{
	private:
		int							_serverFd;
		int							_port;
		std::string					_password;
		std::vector<struct pollfd>	_fds;
		std::map<int, ConnectedUser>	_users;

		void	acceptNew(void);
		void	handleRecv(int fd);
		void	removeUser(int fd);
		void	dispatch(int fd, const IrcMessage &msg);
		void  	handlePass(int fd, const IrcMessage &msg);
		void 	handleNick(int fd, const IrcMessage &msg);
		void  	handleUser(int fd, const IrcMessage &msg);
		void  	handlePing(int fd, const IrcMessage &msg);
		void  	handleQuit(int fd, const IrcMessage &msg);

	public:
		Server(int port, const std::string &password);
		Server(const Server &other);
		Server	&operator=(const Server &other);
		~Server(void);

		void	start(void);
		void	run(void);
		void	sendReply(int fd, const std::string &msg);
};

#endif
