#!/usr/bin/env python3

# Simple and dumb script to send a message to the #podman IRC channel on frenode
# Based on example from: https://pythonspot.com/building-an-irc-bot/

import os
import time
import random
import errno
import socket
import sys

class IRC:

    response_timeout = 30  # seconds
    irc = socket.socket()

    def __init__(self, server, nickname, channel):
        self.server = server
        self.nickname = nickname
        self.channel = channel
        self.irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def _send(self, cmdstr):
        self.irc.send(bytes(cmdstr + '\r\n', 'utf-8'))

    def message(self, msg):
        data = 'PRIVMSG {0} :{1}\r\n'.format(self.channel, msg)
        print(data)
        self._send(data)

    @staticmethod
    def fix_newlines(bufr):
        return bufr.replace('\\r\\n', '\n')

    def _required_response(self, needle, haystack):
        start = time.time()
        end = start + self.response_timeout
        while time.time() < end:
            if haystack.find(needle) != -1:
                return (False, haystack)
            time.sleep(0.1)
            try:
                haystack += str(self.irc.recv(4096, socket.MSG_DONTWAIT))
            except socket.error as serr:
                if serr.errno == errno.EWOULDBLOCK:
                    continue
                raise  # can't handle this
        return (True, haystack)  # Error

    def connect(self, username, password):
        # This is ugly as sin, but seems to be a working send/expect sequence

        print("connecting to: {0}".format(self.server))
        self.irc.connect((self.server, 6667))  #connects to the server
        self._send("USER {0} {0} {0} :I am {0}".format(self.nickname))
        self._send("NICK {0}".format(self.nickname))

        err, haystack = self._required_response('End of /MOTD command.'
                                                ''.format(self.nickname), "")
        if err:
            print(self.fix_newlines(haystack))
            print("Error connecting to {0}".format(self.server))
            return True

        print("Logging in as {0}".format(username))
        self._send("PRIVMSG NickServ :IDENTIFY {0} {1}".format(username, password))
        err, _ = self._required_response("You are now identified for", "")
        if err:
            print("Error logging in to {0} as {1}".format(self.server, username))
            return True

        print("Joining {0}".format(self.channel))
        self._send("JOIN {0}".format(self.channel))
        err, haystack = self._required_response("{0} {1} :End of /NAMES list."
                                                "".format(self.nickname, self.channel),
                                                haystack)
        print(self.fix_newlines(haystack))
        if err:
            print("Error joining {0}".format(self.channel))
            return True
        return False

    def quit(self):
        print("Quitting")
        self._send("QUIT :my work is done here")
        self.irc.close()


if len(sys.argv) < 3:
    print("Error: Must pass desired nick and message as parameters")
else:
    for try_again in (True,False):
        irc = IRC("irc.freenode.net", sys.argv[1], "#podman")
        err = irc.connect(*os.environ.get('IRCID', 'Big Bug').split(" ", 2))
        if err and try_again:
            print("Trying again in 5 seconds...")
            time.sleep(5)
            continue
        elif err:
            break
        irc.message(" ".join(sys.argv[2:]))
        time.sleep(5.0)  # avoid join/quit spam
        irc.quit()
        break
