#include "Server.hpp"
#include "split.hpp"
#include "errcodes.hpp"
#include <algorithm>
#include <string>

int
Server::_cmdKICK(Message const& msg)
{
    if (int rv = msg.expectArgs(2)) {
        return rv == -1 ? rv : 0;
    }
    Client& client = msg.getClient();

    std::string reason;
    if (msg.getArgs().size() > 2) {
        reason = msg.getArgs()[2];
    } else {
        reason = client.nick;
    }
    string_vector const& chans = split(msg.getArgs()[0], ",");
    string_vector const& users = split(msg.getArgs()[1], ",");

    if (users.size() != chans.size()) {
        client.sendCode(ERR_NEEDMOREPARAMS, "KICK", "Not enough parameters");
        return 0;
    }
    for (size_t i = 0; i < users.size(); ++i) {
        std::list<Client>::iterator itClient;
        std::vector<Channel>::iterator itChannel;

        itClient = std::find(_clients.begin(), _clients.end(), users[i]);
        if (itClient == _clients.end()) {
            client.sendCode(ERR_NOSUCHNICK, users[i], "No such nick/channel");
            continue;
        }

        itChannel = std::find(_channels.begin(), _channels.end(), chans[i]);
        if (itChannel == _channels.end()) {
            client.sendCode(ERR_NOSUCHCHANNEL, chans[i], "No such channel");
            continue;
        }

        if (!itChannel->isOnChannel(client)) {
            client.sendCode(ERR_NOTONCHANNEL, chans[i], "You're not on that channel");
            continue;
        }
        if (!itChannel->isOnChannel(*itClient)) {
            client.sendCode(ERR_USERNOTINCHANNEL, users[i] + " " + chans[i],
                    "They aren't on that channel");
            continue;
        }
        if (!itChannel->isOp(client)) {
            client.sendCode(ERR_CHANOPRIVSNEEDED, chans[i], "You're not channel operator");
            continue;
        }
        itChannel->kickClient(client, *itClient, reason);
        if (itChannel->isChannelEmpty()) {
            _channels.erase(itChannel);
            std::list<Client>::iterator itC;
            for (itC = _clients.begin(); itC != _clients.end(); ++itC) {
                itC->isInvited(*itChannel);
            }
        }
    }
    return 0;
}
