"""RPC Server module."""

import sys
import socket
import pickle
from fnmatch import fnmatch
from repr import repr


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


class Server:

    """RPC Server class.  Derive a class to implement a particular service."""

    def __init__(self, address, verbose = VERBOSE):
        if type(address) == type(0):
            address = ('', address)
        self._address = address
        self._verbose = verbose
        self._socket = None
        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._socket.bind(address)
        self._socket.listen(1)
        self._listening = 1

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

    def __del__(self):
        self._close()

    def _close(self):
        self._listening = 0
        if self._socket:
            self._socket.close()
        self._socket = None

    def _serverloop(self):
        while self._listening:
            self._serve()

    def _serve(self):
        if self._verbose: print "Wait for connection ..."
        conn, address = self._socket.accept()
        if self._verbose: print "Accepted connection from %s" % repr(address)
        if not self._verify(conn, address):
            print "*** Connection from %s refused" % repr(address)
            conn.close()
            return
        rf = conn.makefile('r')
        wf = conn.makefile('w')
        ok = 1
        while ok:
            wf.flush()
            if self._verbose > 1: print "Wait for next request ..."
            ok = self._dorequest(rf, wf)

    _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*']

    def _verify(self, conn, address):
        host, port = address
        for pat in self._valid:
            if fnmatch(host, pat): return 1
        return 0

    def _dorequest(self, rf, wf):
        rp = pickle.Unpickler(rf)
        try:
            request = rp.load()
        except EOFError:
            return 0
        if self._verbose > 1: print "Got request: %s" % repr(request)
        try:
            methodname, args, id = request
            if '.' in methodname:
                reply = (None, self._special(methodname, args), id)
            elif methodname[0] == '_':
                raise NameError, "illegal method name %s" % repr(methodname)
            else:
                method = getattr(self, methodname)
                reply = (None, apply(method, args), id)
        except:
            reply = (sys.exc_type, sys.exc_value, id)
        if id < 0 and reply[:2] == (None, None):
            if self._verbose > 1: print "Suppress reply"
            return 1
        if self._verbose > 1: print "Send reply: %s" % repr(reply)
        wp = pickle.Pickler(wf)
        wp.dump(reply)
        return 1

    def _special(self, methodname, args):
        if methodname == '.methods':
            if not hasattr(self, '_methods'):
                self._methods = tuple(self._listmethods())
            return self._methods
        raise NameError, "unrecognized special method name %s" % repr(methodname)

    def _listmethods(self, cl=None):
        if not cl: cl = self.__class__
        names = cl.__dict__.keys()
        names = filter(lambda x: x[0] != '_', names)
        names.sort()
        for base in cl.__bases__:
            basenames = self._listmethods(base)
            basenames = filter(lambda x, names=names: x not in names, basenames)
            names[len(names):] = basenames
        return names


from security import Security


class SecureServer(Server, Security):

    def __init__(self, *args):
        apply(Server.__init__, (self,) + args)
        Security.__init__(self)

    def _verify(self, conn, address):
        import string
        challenge = self._generate_challenge()
        conn.send("%d\n" % challenge)
        response = ""
        while "\n" not in response and len(response) < 100:
            data = conn.recv(100)
            if not data:
                break
            response = response + data
        try:
            response = string.atol(string.strip(response))
        except string.atol_error:
            if self._verbose > 0:
                print "Invalid response syntax", repr(response)
            return 0
        if not self._compare_challenge_response(challenge, response):
            if self._verbose > 0:
                print "Invalid response value", repr(response)
            return 0
        if self._verbose > 1:
            print "Response matches challenge.  Go ahead!"
        return 1
