import os, random

from eventlet import eventrouter
from eventlet import ultramini
from eventlet import api
from eventlet import util
from eventlet import channel

util.emulate_socket()

import socket


NAMES = ['Fred', 'Billy', 'Jimbo', 'Stan', 'Alice', 'Jane']


class FakeUser(object):
    def __init__(self, name):
        self.name = name


class IrcBridge(object):
    def __init__(self, tahc, host, port, nick, ident, realname, chan):
        self.tahc = tahc
        self.host = host
        self.port = port
        self.nick = nick
        self.ident = ident
        self.realname = realname
        self.chan = chan
        self.readbuffer = ''
        self.s=socket.socket()
        self.write_channel = channel.channel()
        api.spawn(self.read_loop)
        api.spawn(self.write_loop)

    def read_loop(self):
        readbuffer = ''
        s = self.s
        s.connect((self.host, self.port))
        s.send("NICK %s\r\n" % (self.nick, ))
        s.send("USER %s %s bla :%s\r\n" % (self.ident, self.host, self.realname))
        s.send("JOIN :%s\r\n" % self.chan)
        s.send("PRIVMSG %s :%s\r\n" % (self.chan, "Hello There!"))
        s.send("PRIVMSG %s :%s\r\n" % (self.chan, "I am a bot"))

        while 1:
            readbuffer += s.recv(1024)
            while '\n' in readbuffer:
                newline_index = readbuffer.index('\n')
                line = readbuffer[:newline_index]
                readbuffer = readbuffer[newline_index+1:]
                print line
                if line.startswith('PING '):
                    self._raw('PONG %s\r\n' % (line[len('PING '):]))
                if 'PRIVMSG' in line:
                    nick, command, channel, rest = line.split(' ', 4)
                    if channel == self.chan:
                        fake_user = FakeUser(nick[1:])
                        self.tahc.post_chat(None, fake_user, rest[1:])
                        self.tahc.post_done(None, fake_user, rest[1:], False)

    def write_loop(self):
        while True:
            towrite = self.write_channel.receive()
            self.s.send(towrite)

    def _raw(self, something):
        self.write_channel.send(something)

    def write(self, something):
        self.write_channel.send(
            "PRIVMSG %s :%s\r\n" % (self.chan, something))

    def topic(self, topic):
        self.write_channel.send("TOPIC %s :%s\r\n" % (self.chan, topic))



class Tahc(eventrouter.Router):
    child_transforms = 'tahc.js'
    child_css = 'tahc.css'

    def event_connect(self, target):
        target.name = random.choice(NAMES)
        target.original_name = target.name
        NAMES.remove(target.name)
        self.topic = getattr(self, 'topic', 'Hello, world')
        bridge.write('%s has joined.' % (target.name, ))

        self.broadcast('new-user', me.name)
        return [self.topic, target.name, [x.name for x in self.targets if x is not target]]

    def event_disconnect(self, target):
        for other in self.targets:
            if other is not target:
                self.msg(other, 'del-user', target.name)
        NAMES.append(target.original_name)
        print "bye", target.original_name
        bridge.write('%s has left.' % (target.name, ))

    def post_nick(self, req, target, nick_info):
        new_nick = nick_info['new-nick'].lower()
        if new_nick not in [x.name.lower() for x in self.targets]:
            bridge.write('%s is now known as %s.' % (nick['old-nick'], nick['new-nick']))
            self.broadcast('rename-user', nick_info)
            target.name = nick_info['new-nick']
        else:
            target.msg('alert', 'Nick is already taken.')

    def post_chat(self, req, target, chat):
        self.bridge('chat', [target.name, chat])

    def post_done(self, req, target, chat, bridge_this=True):
        if bridge_this:
            bridge.write('%s: %s' % (target.name, chat))
        self.render_data('done', target.name)

    def post_topic(self, req, target, topic):
        self.topic = topic
        bridge.topic(topic)
        self.render_data('topic', topic)


if __name__ == '__main__':
    from eventlet import logutil
    from eventlet import httpd

    root = Tahc()
    bridge = IrcBridge(root, 'irc', 6667, 'asdf', 'asdf', 'asdf', '#asdf')
    logger, handler = logutil.file_logger('access.log')

    httpd.server(
        api.tcp_listener(('0.0.0.0', 4269)),
        ultramini.SiteMap(root),
        log=logger)

