#! /usr/bin/env python

# This is an example of an IRC bot which :
#   * Sends on IRC a message when a door is opened / closed
#   * Answers to command "porte" by returning door state
#
# Door state is read from Raspberry PI GPIO using RPi.GPIO
# GPIOs are set with GPIO.BOARD numbering scheme to be interoperable with various hardware versions
#
# WARNING : this a far away from state of art peace of code and
# Example program using irc.bot.
#
# Joel Rosdahl <joel@rosdahl.net>


import RPi.GPIO as GPIO
import irc.bot
import irc.strings
from irc.client import ip_numstr_to_quad, ip_quad_to_numstr

GPIO.setmode(GPIO.BOARD)
GPIO.setup(21, GPIO.IN)
GPIO.setup(19, GPIO.IN)

server_hostname = "irc.geeknode.net"
server_port = 6667
irc_chan = "#faimaison"
bot_name = "didier"


def get_door_state():
    state = []
    state.append("[+] backdoor is opened" if GPIO.input(19) == 0 else "[ ] backdoor is closed")
    state.append("[+] front door is opened" if GPIO.input(21) == 0 else "| ] front door is closed")
    return state


class TestBot(irc.bot.SingleServerIRCBot):
    def __init__(self, channel, nickname, server, port=6667):
        irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
        self.channel = channel

    def on_nicknameinuse(self, c, e):
        c.nick(c.get_nickname() + "_")

    def on_welcome(self, c, e):
        c.join(self.channel)

    def on_privmsg(self, c, e):
        self.do_command(e, e.arguments[0])

    def on_pubmsg(self, c, e):
        a = e.arguments[0].split(":", 1)
        if len(a) > 1 and irc.strings.lower(a[0]) == irc.strings.lower(self.connection.get_nickname()):
            self.do_command(e, a[1].strip())
        return

    def on_dccmsg(self, c, e):
        # non-chat DCC messages are raw bytes; decode as text
        text = e.arguments[0].decode('utf-8')
        c.privmsg("You said: " + text)

    def on_dccchat(self, c, e):
        if len(e.arguments) != 2:
            return
        args = e.arguments[1].split()
        if len(args) == 4:
            try:
                address = ip_numstr_to_quad(args[2])
                port = int(args[3])
            except ValueError:
                return
            self.dcc_connect(address, port)

    def send_msg(self, msg):
        c = self.connection
        print("ok msg %s" % msg)
        c.privmsg(irc_chan, msg)

    def do_command(self, e, cmd):
        nick = e.source.nick
        c = self.connection

        # if cmd == "disconnect":
        #    self.disconnect()
        if cmd == "porte":
            for s in get_door_state():
                c.privmsg(irc_chan, "%s : %s" % (nick, s))
        # elif cmd == "die":
        #    self.die()
        # elif cmd == "stats":
        #    for chname, chobj in self.channels.items():
        #        c.notice(nick, "--- Channel statistics ---")
        #        c.notice(nick, "Channel: " + chname)
        #        users = sorted(chobj.users())
        #        c.notice(nick, "Users: " + ", ".join(users))
        #        opers = sorted(chobj.opers())
        #        c.notice(nick, "Opers: " + ", ".join(opers))
        #        voiced = sorted(chobj.voiced())
        #        c.notice(nick, "Voiced: " + ", ".join(voiced))
        # elif cmd == "dcc":
        #    dcc = self.dcc_listen()
        #    c.ctcp("DCC", nick, "CHAT chat %s %d" % (
        #        ip_quad_to_numstr(dcc.localaddress),
        #        dcc.localport))
        else:
            c.privmsg(irc_chan, nick + " : Hein ? je comprend pas cette commande. Mes commandes sont : 'porte'")


# !/usr/bin/env python3

import time
from time import sleep
import RPi.GPIO as GPIO

pin_back = 19
pin_front = 21

GPIO.setmode(GPIO.BOARD)
GPIO.setup(pin_back, GPIO.IN)  # , pull_up_down=GPIO.PUD_DOWN)
previous_state = None


def main():
    import sys
    server = server_hostname
    port = server_port
    channel = irc_chan
    nickname = bot_name

    bot = TestBot(channel, nickname, server, port)
    bot.connect(server, port, nickname)
    bot.send_msg("hello world")

    def my_callback(channel):
        global previous_state
        # time.sleep(0.2)  # confirm the movement by waiting 1.5 sec
        pin_val = GPIO.input(pin_back)

        if pin_val != previous_state:
            previous_state = pin_val

            if pin_val:  # and check again the input
                bot.send_msg("[ ] CapsLock : DOOR CLOSED !")
            else:
                bot.send_msg("[+] CapsLock : DOOR OPENED !")

    GPIO.add_event_detect(pin_back, GPIO.BOTH, callback=my_callback)
    bot.start()


if __name__ == "__main__":
    main()
