# -*-coding:Latin-1 -*
"""serveur chat (UDP)"""
import socket
import threading
import os

#### intialisation des variables ####
hote = ''
port = 6660
connectes = {}

#### fils secondaires #### 

class FilClient(threading.Thread):
    """fil de connexion client"""
    def __init__(self, cnn):
        """creation du fil"""
        threading.Thread.__init__(self)
        self.cnn = cnn
        
    def run(self):
        """echange avec le client"""
        try:
           nom = self.getName()
           while True:
               #reception du message client
               msgClient = self.cnn.recv(1024)
               print("{}> {}".format(nom, msgClient))
               
               try:
                  #fait suivre le message a tous les clients sauf l'emetteur:
                  for cle in connectes:
                      if cle != self:    
                          connectes[cle].sendall(msgClient)
               except RuntimeError:
                  #pour gérer le changement de taille du dictionnaire 'connectes'
                  #lors de l'arrivee ou du depart d'un client 
                  print("Changement de taille du dictionnaire") 

        except:
            print("Erreur {}".format(self.getName()))
            self.stop()

    def stop(self):
        """ferme le fil client"""
        #fermeture de la connexion avec le client:
        self.cnn.close()
        #on supprime le client de la liste des connectes
        del connectes[self]
        print("Client {} deconnecte.".format(self.getName()))

# Le fil se termine ici    


class Serveur(threading.Thread):
    """serveur TCP pour chat, echange de fichiers ou d'objets..."""
    def __init__(self):
        """creation du serveur"""
        self.serveur_lance = False
        threading.Thread.__init__(self)


    def demarrerServeur(self):
        """demarre le serveur"""
        try:
           self.cnn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
           self.cnn.bind((hote, port))
           self.cnn.listen(5)
           retour = "Le serveur ecoute a present sur le port {}".format(port)
           self.serveur_lance = True
           self.start()
        except:
           retour = "Impossible de demarrer le serveur"
        return retour

    def run(self):
        """boucle de fonctionnement"""
        while self.serveur_lance:
            try:
               #tant que le serveur est lance, il reste disponible a de nouvelles connexions
               cnnClient, adresse = self.cnn.accept()
               #on cree un nouveau fil pour le nouveau client
               client = FilClient(cnnClient)
               client.start()
               #et on ajoute son adresse reseau a la liste des connectes
               nom = client.getName()
               connectes[client] = cnnClient
               print("Client {} connecte, adresse IP {}, port {}.".format(nom, adresse[0], adresse[1]))
            except:
               break        
        
    def stop(self):
        """ferme le serveur"""
        self.serveur_lance = False
        for client in connectes.keys():
            client.stop()
        self.cnn.close()
        print("Serveur ferme")
        
#### fil principal ####
if __name__ == "__main__":
   # si lancement direct:
   s = Serveur()
   print(s.demarrerServeur())
   os.system("pause")
   s.stop()
   print("- Fin -")

   
   
   




    
 

