#!/usr/bin/env python3

import socket
import sys
import traceback
import subprocess
from threading import Thread

def server():
    host = "127.0.0.1"
    port = 65432
    subprocess.call('clear', shell=True)

    try:
        soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        soc.bind((host,port))
        print ('Socket successfully created')
    except:
        print ('Unable to bind to ' + host + " " + str(port))
        sys.exit()

    soc.listen(3)       
    print('Server is listening on port ' + str(port))

    while True:
        conn, addr = soc.accept()
        connected_clients.append(conn)
        print ('Server connected to client ' + str(addr[0]) + " " + str(addr[1]))
        client_message = ('Client connected ' + str(addr[0]) + " " + str(addr[1]))
        broadcast_message(client_message)

        try:
            Thread(target=client_thread, args=(conn, addr)).start()
        except:
            print('Unable to create a thread')
            traceback.print_exc()

    soc.close()


def client_thread(connection, addr, max_buffer_size = 1024):
    is_active = True

    while is_active:
        client_input = connection.recv(max_buffer_size)
        mes = str(client_input.decode('utf-8'))
        all_message = "Msg from " + str(addr[0]) + " " + str(addr[1])+" : "+ mes

        if mes.upper() == 'QUIT':
            close_mess = 'Client left the chat ' + str(addr[0]) + " " + str(addr[1])
            print (close_mess)
            broadcast_message(close_mess)
            connected_clients.remove(connection)
            break

        print (all_message)
        broadcast_message(all_message)

def broadcast_message(message):
    for x in range(0,len(connected_clients)):
        #print (connected_clients[x])
        connected_clients[x].sendall(bytes(message, 'utf-8'))

try:
    connected_clients = []
    server()
except KeyboardInterrupt:
    print ('Interrupted, closing the socket and quitting')
    sys.exit(0)
