"""RPC Client module."""

import sys
import socket
import pickle
import builtins
import os


# Default verbosity (0 = silent, 1 = print connections, 2 = print requests too)
VERBOSE = 1


class Client:

    """RPC Client class.  No need to derive a class -- it's fully generic."""

    def __init__(self, address, verbose = VERBOSE):
        self._pre_init(address, verbose)
        self._post_init()

    def _pre_init(self, address, verbose = VERBOSE):
        if type(address) == type(0):
            address = ('', address)
        self._address = address
        self._verbose = verbose
        if self._verbose: print("Connecting to %s ..." % repr(address))
        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._socket.connect(address)
        if self._verbose: print("Connected.")
        self._lastid = 0 # Last id for which a reply has been received
        self._nextid = 1 # Id of next request
        self._replies = {} # Unprocessed replies
        self._rf = self._socket.makefile('r')
        self._wf = self._socket.makefile('w')

    def _post_init(self):
        self._methods = self._call('.methods')

    def __del__(self):
        self._close()

    def _close(self):
        if self._rf: self._rf.close()
        self._rf = None
        if self._wf: self._wf.close()
        self._wf = None
        if self._socket: self._socket.close()
        self._socket = None

    def __getattr__(self, name):
        if name in self._methods:
            method = _stub(self, name)
            setattr(self, name, method) # XXX circular reference
            return method
        raise AttributeError(name)

    def _setverbose(self, verbose):
        self._verbose = verbose

    def _call(self, name, *args):
        return self._vcall(name, args)

    def _vcall(self, name, args):
        return self._recv(self._vsend(name, args))

    def _send(self, name, *args):
        return self._vsend(name, args)

    def _send_noreply(self, name, *args):
        return self._vsend(name, args, 0)

    def _vsend_noreply(self, name, args):
        return self._vsend(name, args, 0)

    def _vsend(self, name, args, wantreply = 1):
        id = self._nextid
        self._nextid = id+1
        if not wantreply: id = -id
        request = (name, args, id)
        if self._verbose > 1: print("sending request: %s" % repr(request))
        wp = pickle.Pickler(self._wf)
        wp.dump(request)
        return id

    def _recv(self, id):
        exception, value, rid = self._vrecv(id)
        if rid != id:
            raise RuntimeError("request/reply id mismatch: %d/%d" % (id, rid))
        if exception is None:
            return value
        x = exception
        if hasattr(builtins, exception):
            x = getattr(builtins, exception)
        elif exception in ('posix.error', 'mac.error'):
            x = os.error
        if x == exception:
            exception = x
        raise exception(value)

    def _vrecv(self, id):
        self._flush()
        if id in self._replies:
            if self._verbose > 1: print("retrieving previous reply, id = %d" % id)
            reply = self._replies[id]
            del self._replies[id]
            return reply
        aid = abs(id)
        while 1:
            if self._verbose > 1: print("waiting for reply, id = %d" % id)
            rp = pickle.Unpickler(self._rf)
            reply = rp.load()
            del rp
            if self._verbose > 1: print("got reply: %s" % repr(reply))
            rid = reply[2]
            arid = abs(rid)
            if arid == aid:
                if self._verbose > 1: print("got it")
                return reply
            self._replies[rid] = reply
            if arid > aid:
                if self._verbose > 1: print("got higher id, assume all ok")
                return (None, None, id)

    def _flush(self):
        self._wf.flush()


from security import Security


class SecureClient(Client, Security):

    def __init__(self, *args):
        self._pre_init(*args)
        Security.__init__(self)
        self._wf.flush()
        line = self._rf.readline()
        challenge = int(line.strip())
        response = self._encode_challenge(challenge)
        line = repr(int(response))
        if line[-1] in 'Ll': line = line[:-1]
        self._wf.write(line + '\n')
        self._wf.flush()
        self._post_init()

class _stub:

    """Helper class for Client -- each instance serves as a method of the client."""

    def __init__(self, client, name):
        self._client = client
        self._name = name

    def __call__(self, *args):
        return self._client._vcall(self._name, args)
