package controller;

import model.LocalUser;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class ListeningThreadUDP extends ListeningThread{

	private DatagramSocket dgramSocket = null;

	
	/* CONSTRUCTOR OF UserListeningThreadUDP
	 * @parametres 
	 * 		@param s : String => nom du thread
	 * 		@param user : User => utilisateur utilisant ce thread
	 * @description
	 * <p>
	 * 		Appel du constructeur de la classe hérité
	 * 		Création d'un socket d'écoute UDP
	 * </p>
	 */
	public ListeningThreadUDP(String s,Controller controller) { 
		super(s,controller);
		try {
			this.dgramSocket = new DatagramSocket(this.controller.myUser.getPortUDPlistening(),this.controller.myUser.getAddIP());
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	/* run
	 * @description
	 * <p>
	 * 		écoutes les messages UDP tant que l'utilisateur est actif
	 * 		Traitement
	 * 			1) Si demande d'information => envoi ses informations
	 * 			2) Si réception d'information => ajoute les informations
	 * </p>
	 */
	public void run(){ 
		
		// Tant que l'utilisateur est actif on attends les messages des nouveaux utilisateurs et changements des utilisateurs actifs 
		while(true) {

			// Réception du message
			byte[] buffer = new byte[256];
			DatagramPacket inPacket= new DatagramPacket(buffer, buffer.length);
			try {
				dgramSocket.receive(inPacket);
			} catch (Exception e) {
				e.printStackTrace();
			}
			buffer = inPacket.getData();

			// Traitement en fonction du message reçu
			String receiveMsg = new String(buffer);
			String [] tabMsg = receiveMsg.split(":");
			
			
			// si demande d'information d'un nouvel utilisateur
			if(tabMsg.length==3) { 
				InetAddress itsIP = null;
				try {
					itsIP = InetAddress.getByName(tabMsg[0].split("/")[1]); // On récupère l'adresse IP de l'utilisateur distant
				} catch (UnknownHostException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				int senderUDPport = Integer.parseInt(tabMsg[1]); // On récupère le port UDP de l'utilisateur distant
				
				String toSend = controller.myUser.getAddIP().toString()+":"+controller.myUser.getPortTCP()+":"+controller.myUser.getPseudo()+":test";
				DatagramPacket outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),itsIP, senderUDPport);

				try {
					dgramSocket.send(outPacket);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			// Si un nouvel utilisateur passe en mode actif ou changement d'information
			else { 
				try {
					// On récupère l'adresse IP et le port TCP de l'utilisateur distant et ajout à la liste de l'utilisateur utilisant ce thread 
					this.controller.myUser.addRemoteUser(InetAddress.getByName(tabMsg[0].split("/")[1]),Integer.parseInt(tabMsg[1]),tabMsg[2]);
				} catch (NumberFormatException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (UnknownHostException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			
		}
		

	}
	
	/* close
	 * @description
	 * 	<p>
	 * 		Ferme le socket d'écoute UDP
	 * 		Interrompt le thread d'écoute UDP
	 *	</p>
	 */
	public void close() {
		this.dgramSocket.close();
		System.out.println("End of listing thread UDP ("+this.controller.myUser.getPseudo()+")");
		try {
			this.interrupt();
		}catch (Exception e){
			e.printStackTrace();
		}
	}
}
