#! /usr/bin/python3
""" With class and concurrently using threads
    Doesn't want to stop
"""
import threading
import socketserver
import socket
import sys
import signal
import json

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]) 
    try:
        while True:
            json_line = in_stream.readline().strip()
            print("{0} --> {1}".format(client_print, json_line))
            receive_object = json.loads(json_line)
            reply_line = json.dumps(receive_object)
            out_stream.write("{0}\r\n".format(reply_line))
            out_stream.flush()
            print("{0} <-- {1}".format(client_print, reply_line))
    except Exception:
        # You'll get here on end-of-connection
        pass

class JSONHandler(socketserver.BaseRequestHandler):
    """
    Instantiated for each connection
    """
    def handle(self):
        client_address = self.request.getpeername()
        client_print = "{0}:{1}".format(socket.getfqdn(client_address[0]),
                                        client_address[1])
        print("Opening connection with {0}".format(client_print))
        echo_json(self.request)
        print("Closing connection with {0}".format(client_print))

class JSONTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

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)
    try:
        server = JSONTCPServer(("", echo_port), JSONHandler)
        server_thread = threading.Thread(target=server.serve_forever)
        server_thread.daemon = False
        server_thread.start()
        signal.pause()
    except KeyboardInterrupt:
        pass
