#pragma once
#include "Client.hpp"
#include "Message.hpp"
#include "Channel.hpp"
#include <string>
#include <list>
#include <vector>

class Client;
class Channel;

class Server {
private:
    const int _port;
    const std::string _keyword;

    int _efd;
    int _socket;
    bool _dead;

    std::list<Client> _clients;
    std::vector<Channel> _channels;

    int _addFd(int fd) const;
    int _accept(int fd);
    int _receiveMsg(int fd);
    int _processMsg(Client &client);

    int _cmdNICK(Message const& msg);
    int _cmdUSER(Message const& msg);
    int _cmdQUIT(Message const& msg);
    int _cmdPART(Message const& msg);
    int _cmdJOIN(Message const& msg);
    int _cmdPRIVMSG(Message const& msg);
    int _cmdNOTICE(Message const& msg);
    int _cmdKICK(Message const& msg);
    int _cmdMOTD(Message const& msg);
    int _cmdTOPIC(Message const& msg);
    int _cmdPING(Message const& msg);
    int _cmdMODE(Message const& msg);
    int _cmdINVITE(Message const& msg);

    int _welcomeClient(Client& client);

public:
    Server(int port, const std::string& password);
    ~Server();

    int init();
    int wait();

    void removeClient(Client& client);
    void quitClient(Client& client);
    Client *findClient(const std::string& nick);

    bool isLive() const;
};
