# LICENSE
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.


"""server message handler"""
# Numerics aggregated from https://www.alien.net.au/irc/irc2numerics.html


class Server_Events:
    """handles events"""


    def __init__(self, forkbot):
        self.forkbot = forkbot
        self.server_msg = ""
        self.server_msg_info = ""
        self.num_switch = {
            #misc
            "NOTICE": self.not_implemented,

            # start-up
            "001": self.rpl_welcome,      # welcome information
            "002": self.rpl_yourhost,     # server information
            "004": self.not_implemented,  # RPL_MYINFO, TODO
            "005": self.not_implemented,  # RPL_BOUNCE

            # server info
            "251": self.not_implemented,
            "252": self.not_implemented,
            "253": self.not_implemented,
            "254": self.not_implemented,
            "255": self.not_implemented,
            "265": self.not_implemented,
            "266": self.not_implemented,

            # channel info
            "315": self.rpl_synirc_who_end,   # end of WHO
            "332": self.rpl_topic,        # topic of channel
            "333": self.not_implemented,  # ??
            "352": self.rpl_synirc_who,       # response to WHO
            "353": self.rpl_namreply,     # user list
            "366": self.rpl_endofnames,   # end of user list

            # motd
            "372": self.motd,             # motd start/continuation
            "375": self.not_implemented,
            "376": self.motd,             # end of motd

            }

    def not_implemented(self):
        """000"""
        #placeholder function
        pass


    def motd(self):
        """372, 376"""
        # for right now we do not
        # care about the MOTD
        pass


    def rpl_welcome(self):
        """001"""
        self.forkbot.log("welcome recieved")
        self.forkbot.hostmask = self.server_msg.split(" ")[-1].replace("\r", "")
        self.forkbot.log("hostmask is " + self.forkbot.hostmask)


    def rpl_yourhost(self):
        """002"""
        pass

    def rpl_synirc_who_end(self):
        """find out what this numeric for this is"""
        pass

    def rpl_topic(self):
        """332"""
        channel = self.server_msg_info[-1]
        topic = self.server_msg[:-1]
        self.forkbot.channel_topics.update({channel: topic})


    def rpl_synirc_who(self):
        """who request handler"""
        msg_info = self.server_msg_info
        host = msg_info[5]
        nick = msg_info[7]

        self.forkbot.users.hostmask.update({nick: host})


    def rpl_namreply(self):
        """353"""
        names = self.server_msg.split(" ")[:-1]
        channel = self.server_msg_info[-1]

        for name in names:
            name = "".join([x for x in name if x not in "@+~"])
            self.forkbot.users.add_user(channel, name)
        for name in names:
            op_type = ""
            if   name.startswith("~"):
                op_type = "owner"
            elif name.startswith("@"):
                op_type = "operator"
            elif name.startswith("&"):
                op_type = "admin"
            elif name.startswith("+"):
                op_type = "voice"
            if op_type != "":
                self.forkbot.users.add_op(channel, "".join(
                    [x for x in name if x not in "@+&~"]), op_type)


    def rpl_endofnames(self):
        """366"""
        pass


    def process(self, msg_info, msg):
        """processes and delegates the server event to the correct function"""
        self.server_msg_info = msg_info
        self.server_msg = msg

        # find the key given by the server, and
        # execute the function that deals with that key
        try:
            self.num_switch[msg_info[1]]()
        except KeyError as ex:
            self.forkbot.log(f"Unsupported Numeric: {ex}")


    def find_ops(self, nicks):
        """parse the list of nicks given by the server and
        register the ops"""
        owner, operator, voice, none = [], [], [], []
        for nick in nicks:
            if nick.startswith("~"):
                owner.append(nick[1:])
            elif nick.startswith("@"):
                operator.append(nick[1:])
            elif nick.startswith("+"):
                voice.append(nick[1:])
            else:
                none.append(nick)
        ops = {
            "owner": owner,
            "operator": operator,
            "voice": voice,
            "none": none
            }
        return ops
