#! /usr/bin/python3

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

# CSCI 373.001 starter

import re
import socket
import threading
from fetch_and_add_register import FetchAndAddRegister

PORT = 22222

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

class FetchAndAddSession(threading.Thread):
    """ Class for Fetch And Add 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:
                increment = int(mat.group(1))
                repstr = self.reg.fetch_and_add(increment)
                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 fetch_and_add_server():
    """Fetch and Add networked server"""
    reg = FetchAndAddRegister()

    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 = FetchAndAddSession(reg, strm, addr)
            thread_session.start()
    except KeyboardInterrupt:
        print('Exiting')
        server_socket.close()


if __name__ == "__main__":
    fetch_and_add_server()
