#!/usr/bin/env python
import urllib2
import re
import functools

from . import BOXEE_HTTP_PORT_DEFAULT, CommandError
from .utils import MultiBoolCallbackHandler

class Command(object):
    '''

    '''


    RESPONSE_EXPR = re.compile(r"<html>\n<li>(.*?)</html>")

    def __init__(self, host, port, command):
        self.host = host
        self.port = port
        self.command = command
        self._url = ("http://%s:%d/xbmcCmds/xbmcHttp?command=%s"
                     % (host, port, command))

    def get_url(self):
        return self._url

    def extract_response_value(self, response_text):
        m = self.RESPONSE_EXPR.match(response_text)
        if m:
            return m.groups()[0]
        return None

    def handle_response_value(self, response_value):
        raise NotImplementedError("command sub-classes required")

    def _handle_response(self, response):
        response_text = self.extract_response_value(response.read())
        if response.getcode()==200 and response_text is not None:
            if response_text.startswith("Error:"):
                raise CommandError(response_text.split(":", 1)[1].strip())
            return response_text
        return None

    def handle_response(self, response):
        resp_value = self._handle_response(response)
        return self.handle_response_value(resp_value)
            
    def run(self):
        resp = self.send_request()

    def __unicode__(self):
        return self.command

    def __repr__(self):
        return (u'<%s host="%s" port=%s command="%s">'
                % (self.__class__.__name__, self.host, self.port,
                   self.command))


def simple_command_runner(cmd, cb=None):
    try:
        res = cmd.handle_response(urllib2.urlopen(cmd.get_url(), timeout=1))
        if cb:
            cb(res)
    except urllib2.URLError, e:
        raise CommandError(e)


class CommandBool(Command):

    def handle_response_value(self, response_value):
        if response_value=="OK":
            return True
        raise CommandError("Unexpected response")

def _get_bool_command(command):
    return functools.partial(CommandBool, command=command)


_COMMAND_PAUSE = _get_bool_command("Pause")
_COMMAND_STOP = _get_bool_command("Stop")
_COMMAND_MUTE = _get_bool_command("Mute")
_COMMAND_PLAYNEXT = _get_bool_command("PlayNext")
_COMMAND_PLAYPREV = _get_bool_command("PlayPrev")


class CommandSetValue(CommandBool):

    def __init__(self, host, port, command, value):
        command = "%s(%s)" % (command, int(value))
        super(CommandSetValue, self).__init__(host, port, command)


def _get_setval_command(command):
    return functools.partial(CommandSetValue, command=command)    

_COMMAND_SETVOLUME = _get_setval_command("SetVolume")
_COMMAND_SEEKPERCENTAGE = _get_setval_command("SeekPercentage")
_COMMAND_SEEKPERCENTAGERELATIVE = _get_setval_command("SeekPercentageRelative")

class CommandSendKey(CommandBool):

    def __init__(self, host, port, key_code):