#! /usr/bin/python3

"""Sample server for CSCI 373.001 class
"""

# CSCI 373.001 starter

import re
import socket
import threading
from compare_and_swap_register import CompareAndSwapRegister

PORT = 33333

PATTERN = re.compile(r'^\s*(\d+)\s+(\d+)\s*\n$')

class CompareAndSwapSession(threading.Thread):
    """ Class for Compare And Swap session """
    def __init__(self, reg, strm, addr):
        threading.Thread.__init__(self)
        self.reg = reg
        self.strm = strm
        self.addr = addr
    def run(self):
        """ Routine to process one connection"""
        print("Connection open:  ", self.addr)
        instrm = self.strm.makefile('r')
        outstrm = self.strm.makefile('w')
        line = instrm.readline()
        while line:
            print("{0} -> {1}".format(self.addr, line[:-1]))
            mat = PATTERN.match(line)
            if mat is None:
                repl = 'Bad Syntax'
            else:
                oldval = int(mat.group(1))
                newval = int(mat.group(2))
                repstr = self.reg.compare_and_swap(oldval, newval)
                repl = str(repstr)
            outstrm.write(repl+'\n\r')
            outstrm.flush()
            line = instrm.readline()
        instrm.close()
        outstrm.close()
        self.strm.close()
        print("Connection closed: ", self.addr)

def compare_and_swap_server():
    """Compare and Swap networked server"""
    reg = CompareAndSwapRegister()

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server_socket.bind(('', PORT))
        server_socket.listen(1)
        while True:
            strm, addr = server_socket.accept()
            thread_session = CompareAndSwapSession(reg, strm, addr)
            thread_session.start()
    except KeyboardInterrupt:
        print('Exiting')
        server_socket.close()


if __name__ == "__main__":
    compare_and_swap_server()
