import select
import socket
import struct
import sys
import types

VERBOSE = None

class SocketProtocol:
    """A simple protocol for sending strings across a socket"""
    BUF_SIZE = 8192

    def __init__(self, sock):
        self.sock = sock
        self._buffer = ''
        self._closed = 0

    def close(self):
        self._closed = 1
        self.sock.close()

    def send(self, buf):
        """Encode buf and write it on the socket"""
        if VERBOSE:
            VERBOSE.write('send %d:%s\n' % (len(buf), `buf`))
        self.sock.send('%d:%s' % (len(buf), buf))

    def receive(self, timeout=0):
        """Get next complete string from socket or return None

        Raise EOFError on EOF
        """
        buf = self._read_from_buffer()
        if buf is not None:
            return buf
        recvbuf = self._read_from_socket(timeout)
        if recvbuf is None:
            return None
        if recvbuf == '' and self._buffer == '':
            raise EOFError
        if VERBOSE:
            VERBOSE.write('recv %s\n' % `recvbuf`)
        self._buffer = self._buffer + recvbuf
        r = self._read_from_buffer()
        return r

    def _read_from_socket(self, timeout):
        """Does not block"""
        if self._closed:
            return ''
        if timeout is not None:
            r, w, x = select.select([self.sock], [], [], timeout)
        if timeout is None or r:
            return self.sock.recv(self.BUF_SIZE)
        else:
            return None

    def _read_from_buffer(self):
        buf = self._buffer
        i = buf.find(':')
        if i == -1:
            return None
        buflen = int(buf[:i])
        enclen = i + 1 + buflen
        if len(buf) >= enclen:
            s = buf[i+1:enclen]
            self._buffer = buf[enclen:]
            return s
        else:
            self._buffer = buf
        return None

# helpers for registerHandler method below

def get_methods(obj):
    methods = []
    for name in dir(obj):
        attr = getattr(obj, name)
        if callable(attr):
            methods.append(name)
    if type(obj) == types.InstanceType:
        methods = methods + get_methods(obj.__class__)
    if type(obj) == types.ClassType:
        for super in obj.__bases__:
            methods = methods + get_methods(super)
    return methods

class CommandProtocol:
    def __init__(self, sockp):
        self.sockp = sockp
        self.seqno = 0
        self.handlers = {}

    def close(self):
        self.sockp.close()
        self.handlers.clear()

    def registerHandler(self, handler):
        """A Handler is an object with handle_XXX methods"""
        for methname in get_methods(handler):
            if methname[:7] == "handle_":
                name = methname[7:]
                self.handlers[name] = getattr(handler, methname)

    def send(self, cmd, arg='', seqno=None):
        if arg:
            msg = "%s %s" % (cmd, arg)
        else:
            msg = cmd
        if seqno is None:
            seqno = self.get_seqno()
        msgbuf = self.encode_seqno(seqno) + msg
        self.sockp.send(msgbuf)
        if cmd == "reply":
            return
        reply = self.sockp.receive(timeout=None)
        r_cmd, r_arg, r_seqno = self._decode_msg(reply)
        assert r_seqno == seqno and r_cmd == "reply", "bad reply"
        return r_arg

    def _decode_msg(self, msg):
        seqno = self.decode_seqno(msg[:self.SEQNO_ENC_LEN])
        msg = msg[self.SEQNO_ENC_LEN:]
        parts = msg.split(" ", 2)
        if len(parts) == 1:
            cmd = msg
            arg = ''
        else:
            cmd = parts[0]
            arg = parts[1]
        return cmd, arg, seqno

    def dispatch(self):
        msg = self.sockp.receive()
        if msg is None:
            return
        cmd, arg, seqno = self._decode_msg(msg)
        self._current_reply = seqno
        h = self.handlers.get(cmd, self.default_handler)
        try:
            r = h(arg)
        except TypeError, msg:
            raise TypeError, "handle_%s: %s" % (cmd, msg)
        if self._current_reply is None:
            if r is not None:
                sys.stderr.write("ignoring %s return value type %s\n" % \
                                 (cmd, type(r).__name__))
            return
        if r is None:
            r = ''
        if type(r) != types.StringType:
            raise ValueError, "invalid return type for %s" % cmd
        self.send("reply", r, seqno=seqno)

    def reply(self, arg=''):
        """Send a reply immediately

        otherwise reply will be sent when handler returns
        """
        self.send("reply", arg, self._current_reply)
        self._current_reply = None

    def default_handler(self, arg):
        sys.stderr.write("WARNING: unhandled message %s\n" % arg)
        return ''

    SEQNO_ENC_LEN = 4

    def get_seqno(self):
        seqno = self.seqno
        self.seqno = seqno + 1
        return seqno

    def encode_seqno(self, seqno):
        return struct.pack("I", seqno)

    def decode_seqno(self, buf):
        return struct.unpack("I", buf)[0]


class StdioRedirector:
    """Redirect sys.std{in,out,err} to a set of file-like objects"""

    def __init__(self, stdin, stdout, stderr):
        self.stdin = stdin
        self.stdout = stdout
        self.stderr = stderr

    def redirect(self):
        self.save()
        sys.stdin = self.stdin
        sys.stdout = self.stdout
        sys.stderr = self.stderr

    def save(self):
        self._stdin = sys.stdin
        self._stdout = sys.stdout
        self._stderr = sys.stderr

    def restore(self):
        sys.stdin = self._stdin
        sys.stdout = self._stdout
        sys.stderr = self._stderr

class IOWrapper:
    """Send output from a file-like object across a SocketProtocol

    XXX Should this be more tightly integrated with the CommandProtocol?
    """

    def __init__(self, name, cmdp):
        self.name = name
        self.cmdp = cmdp
        self.buffer = []

class InputWrapper(IOWrapper):
    def write(self, buf):
        # XXX what should this do on Windows?
        raise IOError, (9, '[Errno 9] Bad file descriptor')

    def read(self, arg=None):
        if arg is not None:
            if arg <= 0:
                return ''
        else:
            arg = 0
        return self.cmdp.send(self.name, "read,%s" % arg)

    def readline(self):
        return self.cmdp.send(self.name, "readline")

class OutputWrapper(IOWrapper):
    def write(self, buf):
        self.cmdp.send(self.name, buf)

    def read(self, arg=None):
        return ''

class RemoteInterp:
    def __init__(self, sock):
        self._sock = SocketProtocol(sock)
        self._cmd = CommandProtocol(self._sock)
        self._cmd.registerHandler(self)

    def run(self):
        try:
            while 1:
                self._cmd.dispatch()
        except EOFError:
            pass

    def handle_execfile(self, arg):
        self._cmd.reply()
        io = StdioRedirector(InputWrapper("stdin", self._cmd),
                             OutputWrapper("stdout", self._cmd),
                             OutputWrapper("stderr", self._cmd))
        io.redirect()
        execfile(arg, {'__name__':'__main__'})
        io.restore()
        self._cmd.send("terminated")

    def handle_quit(self, arg):
        self._cmd.reply()
        self._cmd.close()

def startRemoteInterp(id):
    import os
    # UNIX domain sockets are simpler for starters
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    sock.bind("/var/tmp/ri.%s" % id)
    try:
        sock.listen(1)
        cli, addr = sock.accept()
        rinterp = RemoteInterp(cli)
        rinterp.run()
    finally:
        os.unlink("/var/tmp/ri.%s" % id)

class RIClient:
    """Client of the remote interpreter"""
    def __init__(self, sock):
        self._sock = SocketProtocol(sock)
        self._cmd = CommandProtocol(self._sock)
        self._cmd.registerHandler(self)

    def execfile(self, file):
        self._cmd.send("execfile", file)

    def run(self):
        try:
            while 1:
                self._cmd.dispatch()
        except EOFError:
            pass

    def handle_stdout(self, buf):
        sys.stdout.write(buf)
##        sys.stdout.flush()

    def handle_stderr(self, buf):
        sys.stderr.write(buf)

    def handle_stdin(self, arg):
        if arg == "readline":
            return sys.stdin.readline()
        i = arg.find(",") + 1
        bytes = int(arg[i:])
        if bytes == 0:
            return sys.stdin.read()
        else:
            return sys.stdin.read(bytes)

    def handle_terminated(self, arg):
        self._cmd.reply()
        self._cmd.send("quit")
        self._cmd.close()

def riExec(id, file):
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    sock.connect("/var/tmp/ri.%s" % id)
    cli = RIClient(sock)
    cli.execfile(file)
    cli.run()

if __name__ == "__main__":
    import getopt

    SERVER = 1
    opts, args = getopt.getopt(sys.argv[1:], 'cv')
    for o, v in opts:
        if o == '-c':
            SERVER = 0
        elif o == '-v':
            VERBOSE = sys.stderr
    id = args[0]

    if SERVER:
        startRemoteInterp(id)
    else:
        file = args[1]
        riExec(id, file)
