from __future__ import with_statement
import fcntl
import sys
import os
import socket
import asyncore

STEP = 10000

if not os.path.exists('uuid.txt'):
    with open('uuid.txt', 'wb+') as f:
        f.write('0')

def uuids():
    while True:
        with open('uuid.txt', 'rb+') as uuid_file:
            fcntl.lockf(uuid_file.fileno(), fcntl.LOCK_EX)
            min = int(uuid_file.read() or 0)
            max = min + STEP
            uuid_file.seek(0)
            uuid_file.write(str(max))
            uuid_file.flush()
            fcntl.lockf(uuid_file.fileno(), fcntl.LOCK_UN)
        for uuid in xrange(min, max):
            yield str(uuid)
uuids = uuids()


class UUIDConnection(asyncore.dispatcher):
    def __init__(self, sock):
        self.data = None
        asyncore.dispatcher.__init__(self, sock)

    def writable(self):
        return bool(self.data)
    
    def handle_write(self):
        self.send(self.data + "\n")
        self.data = None

    def handle_read(self):
        line = self.recv(1024)
        line = line.strip()

        if line == 'gee':
            self.data = uuids.next()
        elif line == 'quit':
            self.close()
        else:
            self.data = "ERROR"


class UUIDServer(asyncore.dispatcher):
    def __init__(self, port=8007):
        asyncore.dispatcher.__init__(self)
        self.port = port
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.bind(("", port))
        self.listen(1)

    def handle_accept(self):
        channel, addr = self.accept()
        UUIDConnection(channel)

if __name__ == '__main__':
    server = UUIDServer()
    asyncore.loop()