#pragma once
#include "Client.hpp"
#include "Server.hpp"
#include "split.hpp"
#include <set>
#include <string>

class Client;
class Server;

class Channel {
private:
    std::set<Client*> _clients;
    std::set<Client*> _op_clients;
    std::string const _name;
    std::string _topic;

    //Channel modes
    bool _fInviteOnly;
    bool _fTopicRestric;
    std::string _keyword;
    size_t _userLimit;
public:
    Channel(std::string const& name, Client& client);
    Channel(Channel const& src);

    bool addClient(Client& client);
    bool addOp(Client& client);
    bool removeClient(Client& client);
    bool removeOp(Client& client);
    bool partClient(Client& client, std::string const& reason = "");
    bool kickClient(Client& client, Client& victim, std::string const& reason);
    size_t numClients() const;

    int sendMessage(std::string const& msg, Client const* client = NULL) const;
    int sendNotice(std::string const& msg, Client const& client) const;

    int sendTopic(Client& client) const;
    int setTopic(Client& client, std::string const& newTopic);

    int setMode(Server& server, Client& client, string_vector const& args);
    int sendMode(Client& client);

    std::string const& getName() const;
    size_t getUserLimit() const;
    bool isInviteOnly() const;
    std::string const& getKeyword() const;
    bool areOnChannel(Client& c1, Client&  c2) const;
    bool isOnChannel(Client& c1) const;
    bool isOp(Client& client) const;

    bool isChannelEmpty() const;

    Channel& operator=(Channel const& rhs);
    bool operator==(Channel const& rhs) const;
    bool operator==(std::string const& name) const;
};
