package rsx.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;

/**
 * Broadcast pour trouver un serveur
 *
 * @author Arthur Brandao
 */
public class Broadcast {

    /**
     * Port pour la socket UDP
     */
    protected int port;
    
    /**
     * Le message à envoyer
     */
    protected String msg;
    
    /**
     * TImeout
     */
    protected int timeout = 5000;
    
    /**
     * Taille du buffer pour l'envoi
     */
    protected int bufferSize = 1024;
    
    /**
     * Liste des serveurs ayant répondu
     */
    protected ArrayList<InetAddress> servers = new ArrayList<>();
    
    /* --- Constructeurs --- */

    /**
     * Creation d'un Broadcast
     * @param port Le port à utiliser
     */
    public Broadcast(int port) {
        this.port = port;
        this.msg = "looking for bomberstudent servers";
    }

    /**
     * Creation d'un Broadcast
     * @param port Le port à utiliser
     * @param msg Le message à envoyer
     */
    public Broadcast(int port, String msg) {
        this.port = port;
        this.msg = msg;
    }
    
    /* --- Methodes --- */

    /**
     * Cherche les serveurs
     * @param answer La reponse attendu du serveur
     * @return Reussite
     */
    public boolean search(String answer) {
        //Creation socket
        DatagramSocket socket = null;
        try {
            socket = new DatagramSocket();
            socket.setBroadcast(true);
            socket.setSoTimeout(this.timeout);
        } catch (SocketException ex) {
            System.err.println("Erreur creation de la socket : " + ex.getMessage());
            return false;
        }

        //Envoi message
        byte[] buffer = this.msg.getBytes();
        DatagramPacket packet;
        try {
            packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("255.255.255.255"), this.port);
            socket.send(packet);
        } catch (UnknownHostException ex) {
            System.err.println("Erreur hote inconnu : " + ex.getMessage());
            return false;
        } catch (IOException ex) {
            System.err.println("Erreur IO : " + ex.getMessage());
            return false;
        }
        
        //Attente reponse
        try {
            while (true) {
                //Recepetion reponse
                byte[] tampon = new byte[this.bufferSize];
                DatagramPacket dp = new DatagramPacket(tampon, tampon.length);
                socket.receive(dp);
                String reponse = new String(dp.getData(), 0, dp.getLength());
                //Analyse reponse
                if(reponse.equals(answer)){
                    this.servers.add(dp.getAddress());
                }
            }
        } catch (SocketTimeoutException ex) {
            //Rien on fini la methode
        } catch (IOException ex) {
            System.err.println("Erreur IO : " + ex.getMessage());
            return false;
        }
        
        //Fin
        socket.close();
        return true;
    }
    
    /**
     * Vide la liste des serveurs
     */
    public void clean(){
        this.servers = new ArrayList<>();
    }
    
    /* --- Getter/Setter --- */

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public int getBufferSize() {
        return bufferSize;
    }

    public void setBufferSize(int bufferSize) {
        this.bufferSize = bufferSize;
    }
    
    public ArrayList<InetAddress> getServers(){
        return new ArrayList<>(this.servers);
    }

}
