"""RPC Server module."""

import sys
import socket
import pickle
from fnmatch import fnmatch
from reprlib 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, method(*args), id)
        except:
            reply = (sys.exc_info()[:2], 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 = sorted([x for x in cl.__dict__.keys() if x[0] != '_'])
        for base in cl.__bases__:
            basenames = self._listmethods(base)
            basenames = list(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):
        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
