from httpserver import ResponseHandler, file_handler_factory
from client import Client
from clientevent import ClientEvent
import os

here = os.path.dirname(os.path.abspath(__file__))

class CommandPipe(ResponseHandler):
    engine = None # set on cls.__dict__ from engine.py

    def __init__(self, config, request, channel):
        self.config = config
        self.request = request
        self.channel = channel
        self.initialized = False
        self.id = 0

    def next(self):
        if self.initialized:
            if self.id not in self.engine.clients:
                self.engine.add_client(self.id,
                                       Client(self.config, self.id,
                                              self.channel))
            else:
                client = self.engine.clients[self.id]
                client.outchannel.refresh_channel(self.channel)
            # hand control over to the engine
            return None
        self.initialized = True
        id = self.id = self.get_id()
        return (
            '%s 200 Ok\r\n'
            'Content-Type: text/plain\r\n'
            '\r\n'
            '%s\r\n'
        ) % (self.request.httpver, id)

    def get_id(self):
        if '?' in self.request.path:
            form = self.request.form
            id = int(form.getvalue('channelid'))
        else:
            id = self.get_new_id()
        return id

    _last = [0] # shared between subclasses
    def get_new_id(self):
        self._last[0] = self._last[0] + 1
        return self._last[0]

class ClientEventPage(ResponseHandler):
    engine = None # set on cls.__dict__ from engine.py

    def __init__(self, config, request, channel):
        self.config = config
        self.request = request
        self.channel = channel
        self.done = False

    def next(self):
        if self.done:
            raise StopIteration()
        if not self.request.body:
            msg = 'Please provide an id and event information'
            return self.error(msg)
        data = [c.strip() for c in self.request.body.strip().split('\n')]
        if len(data) != 2:
            msg = 'Unexpected amount of data'
            return self.error(msg)
        id = int(data[0].strip())
        eventdata = data[1].strip()
        event = ClientEvent(eventdata)
        self.engine.clients[id].inchannel.add_event(event)
        self.done = True
        return (
            'HTTP/1.0 204 No Content\r\n'
            '\r\n'
        )

    def error(self, msg):
        return (
            '%s 500 Server Error\r\n'
            'Content-Type: text/plain\r\n'
            '\r\n'
            '%s\r\n'
        ) % (self.request.httpver, msg)

def getpaths(startpath):
    # yields all paths to all non-hidden files, recursively
    for child in os.listdir(startpath):
        if child.startswith('.'):
            continue
        path = os.path.join(startpath, child)
        yield path
        if os.path.isdir(path):
            for path in getpaths(path):
                yield path

def add_static_files(app):
    static = os.path.join(here, 'static')
    for path in getpaths(static):
        if (os.path.isfile(path) and
                os.path.splitext(path)[1] in ('.js', '.css')):
            application['/static' + path[len(static):]] = {
                'GET': file_handler_factory(path),
            }

application = {
    '/out': {'GET': CommandPipe},
    '/in': {'POST': ClientEventPage},
}
add_static_files(application)


