package src.Controller;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import src.Protocoles.*;
import src.Model.*;
/**
*
* Classe recapitulant toutes les actions possibles pour un utilisateur
*
*/
public class ChatApp extends Thread{
/* Liste des utilisateurs actifs */
private ListUtilisateurs actifUsers ;
/* Map on l'on stocke localement les historiques des messages */
private Map mapHistorique ;
private boolean historiqueAvailable = true;
/* ChatApp est associe a un utilisateur */
private Utilisateur me;
/**
* Constructeur de l'application de chat
*
* @param pseudo Pseudo de l'utilisateur
* @param port Port de communication
*/
public ChatApp(String pseudo, Integer port){
this.actifUsers = new ListUtilisateurs() ;
// Recuperer adresse IP de l'utilisateur
InetAddress ip = null ;
ip = UDPEchange.getCurrentIp();
this.me = new Utilisateur(pseudo,port,ip);
this.actifUsers.addList(getMe());
this.mapHistorique = new HashMap() ;
}
/**
* Mettre a jour dans Maphistorique, l'historique avec un utilisateur dont le nom est pseudo
*
* @param pseudo Pseudo de l'utilisateur
* @param h nouvel Historique entre les deux utilisateurs
*/
public synchronized void majHistorique(Historique h) {
getMapHistorique().put(h.getUser2().getPseudo(),h);
}
/*public void majHistorique2(MessageHorodate mh, String pseudo) {
Historique h = getMapHistorique().get(pseudo);
//h.addMessage(mh);
getMapHistorique().put(h.getUser2().getPseudo(),h);
}*/
public void majHistorique2(String mh, String pseudo) {
Historique h = getMapHistorique().get(pseudo);
MessageHorodate msghor = new MessageHorodate(this.getMe(),this.getMe(),"rien",1);
System.out.println(">>"+mh+"<<");
System.out.print(msghor.getDateHorodatage());
System.out.println(msghor.getDestinataire());
System.out.println(msghor.getSource());
System.out.println(msghor.getType());
h.addMessage(msghor);
getMapHistorique().put(h.getUser2().getPseudo(),h);
}
/**
* Modification du pseudo de l'utilisateur
* Envoie en broadcast ses informations utilisateurs et son nouveau pseudo
*
* @param nouveau correspond au nouveau pseudo
* @return False si modiferPseudo a echoue, True sinon
*/
public Boolean modifierPseudo(String nouveau) throws IOException {
// Message que l'on envoie à tous les utilisateurs actifs
String broadcastMessage = "Demande Modification Pseudo\n" + this.getMe().toString() + "\n" + nouveau + "\n";
UDPEchange.EnvoiBroadcast(broadcastMessage);
try {
Thread.sleep(2000);
/* L'utilisateur doit attendre la reponse de tous les utilisateurs connectes
* pour savoir si son pseudo est accepte
*/
} catch (InterruptedException e) {
e.printStackTrace();
}
if (UDPEchange.getPseudoValide()) {
System.out.println("Modification pseudo reussie");
//Envoi un msg en broadcast a tout les utilisateurs pour les prevenir de son nouveau pseudo//
broadcastMessage = "Modification pseudo reussie\n" + this.getMe().toString() + "\n" + nouveau + "\n";
UDPEchange.EnvoiBroadcast(broadcastMessage);
//-------Change son propre nom d'utilisateur-------//
this.getActifUsers().modifierList(this.getMe().getPseudo(), nouveau);
this.getMe().setPseudo(nouveau);
System.out.println("Changement pseudo accepte, nouvelle liste des utilisateurs actifs:");
this.getActifUsers().afficherListeUtilisateurs();
return true;
}
else
{
System.out.println("Echec Modification pseudo");
return false;
}
}
/**
* Methode appelee lors de la connexion d'un nouvel utilisateur.
* Il va prevenir les utilisateurs du reseau de son arrivee.
* @return False si Connexion a echoue, True sinon
*/
public Boolean connexion() throws IOException {
// Message que l'on envoie à tous les utilisateurs actifs
String broadcastMessage = "Connexion\n" + this.getMe().toString() ;
UDPEchange.EnvoiBroadcast(broadcastMessage);
try {
Thread.sleep(2000); // L'utilisateur doit attendre la reponse de tous les utilisateurs connectes
} catch (InterruptedException e) {
e.printStackTrace();
}
if (UDPEchange.getConnecte()) {
System.out.println("Connexion reussie");
return true;
}
else
{
System.out.println("Connexion echoue");
UDPEchange.setConnecte(true);
return false ;
}
}
/**
* Methode appelee lors de la deconnexion de l'utilisateur.
* Il va prevenir les utilisateurs du reseau de son depart.
*
*/
public void deconnexion() throws IOException {
// Message que l'on envoie à tous les utilisateurs actifs
String broadcastMessage = "Deconnexion\n" + this.getMe().toString() ;
UDPEchange.EnvoiBroadcast(broadcastMessage);
System.exit(1);
}
/**
* Getter
* @return Utilisateur associee a ChatApp
*/
public Utilisateur getMe() {
return me;
}
/**
* Getter
* @return Liste des utilisateurs actifs associee a ChatApp
*/
public ListUtilisateurs getActifUsers() {
return actifUsers;
}
/**
* Getter
* @return la map des historiques
*/
public Map getMapHistorique() {
return mapHistorique;
}
/**
* Obtenir l'historique entre deux utilisateurs
* @param pseudo Pseudo de l'utilisateur dont on souhaite obtenir l'historique
* @return Un historique
*/
public synchronized Historique getHist(String pseudo) {
Historique h = this.mapHistorique.get(pseudo);
if( h != null) {
return h ;
}
else {
h = new Historique(this.me, this.getActifUsers().getPseudoList(pseudo));
return h ;
}
}
public static void main (String[] args) throws IOException {
ChatApp app = new ChatApp(args[0],Integer.parseInt(args[1])) ;
System.out.println("On lance le chatapp");
ExecutorService execUDP = Executors.newFixedThreadPool(1000);
execUDP.submit(new RunnerEcouteUDP(app));
try {
app.connexion();
} catch (IOException e) {
e.printStackTrace();
}
ExecutorService execTCP = Executors.newFixedThreadPool(1000);
System.out.println("On lance l'écoute TCP de chatapp");
execTCP.submit(new RunnerEcouteTCP(app));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(app.getMe().getPseudo().equals("Marvel")) {
app.getHist("Doudou").afficher10derniers();
System.out.println("Tentative de connexion avec Doudou");
TCPEchange.demarrerSession(app, app.actifUsers.getPseudoList("Doudou"));
}
}
public boolean isHistoriqueAvailable() {
return historiqueAvailable;
}
public void setHistoriqueAvailable(boolean historiqueAvailable) {
this.historiqueAvailable = historiqueAvailable;
}
}