#! /usr/bin/python3

# Instead of following the example at the socketserver page,
# I followed the one by keenerd@gmail.com at
#    http://kmkeen.com/socketserver/2009-02-07-07-52-15.html

""" With class and concurrently using threads
"""
import threading
import socketserver
import socket
import sys
import signal
import json
import random
import time

def echo_json(json_socket):
    """Echo some JSON
    """
    in_stream = json_socket.makefile("r")
    out_stream = json_socket.makefile("w")
    client_address = json_socket.getpeername()
    client_print = "{0}:{1}".format(socket.getfqdn(client_address[0]),
                                    client_address[1])
    print("{0} OPENED".format(client_print))
    sys.stdout.flush()
    try:
        next_msg = "NEXT"
        rand_loops = random.randrange(2, 9)
        for tries in range(rand_loops):
            out_stream.write(next_msg+"\r\n")
            out_stream.flush()
            print("{0} <-- {1}".format(client_print, next_msg))
            sys.stdout.flush()
            json_line = in_stream.readline().strip()
            print("{0} --> {1}".format(client_print, json_line))
            sys.stdout.flush()
            receive_object = json.loads(json_line)
            rand_wait_root = random.randrange(10, 20, 1)
            rand_wait_send = rand_wait_root * rand_wait_root / 100.0
            time.sleep(rand_wait_send)
    except Exception:
        # You'll get here on end-of-connection
        pass
    print("{0} CLOSED".format(client_print))
    sys.stdout.flush()

class JSONHandler(socketserver.BaseRequestHandler):
    """
    Instantiated for each connection
    """
    def handle(self):
        client_address = self.request.getpeername()
        echo_json(self.request)

class JSONTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    # Taken from http://kmkeen.com/socketserver/2009-02-07-07-52-15.html
    #
    # Ctrl-C will cleanly kill all spawned threads
    daemon_threads = True
    # much faster rebinding
    # allow_reuse_address = True
    def __init__(self, server_address, RequestHandlerClass):
        socketserver.TCPServer.__init__(self, server_address,
                                        RequestHandlerClass)

if __name__ == "__main__":
    if len(sys.argv) <= 1:
        echo_port = 3210
    else:
        try:
            echo_port = int(sys.argv[1])
        except ValueError:
            print("Invalid port number: {0}".format(sys.argv[1]))
            sys.exit(2)
    server = JSONTCPServer(("", echo_port), JSONHandler)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        sys.exit(0)
    print("You should not be here")
    sys.stdout.flush()
