package chatapp.Model;

import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;

/**
 * <p>
 * Classe représentant la liste des utilisateurs actifs, stockée localement.
 * </p>
 */
public class ListUtilisateurs {

    // On conserve dans cette liste tout les utilisateurs actuellement actifs
    private ArrayList<Utilisateur> actifUsers ;

    /**
     * Constructeur : initialise la liste 'actifUsers'
     */
    public ListUtilisateurs() {
        this.actifUsers = new ArrayList<>() ;
    }

    /**
     * Ajouter des utilisateurs actifs dans l'attribut liste 'actifUsers'
     * @param u On va rajouter cet utilisateur dans la liste
     */
    public synchronized void addList(Utilisateur u) {
        if (! this.appartient(u)){
            this.actifUsers.add(u);
        }
    }

    /**
     * Récupérer un utilisateur à partir de son pseudo.
     * @param pseudo Pseudo de l'utilisateur que l'on souhaite retrouver
     * @return L'utilisateur associé à ce pseudo
     */
    public Utilisateur getPseudoList(String pseudo) {
        for(Utilisateur elem: this.actifUsers)
        {
            if (elem.getPseudo().equals(pseudo) ) {
                return elem ;
            }
        }
        return null ;
    }

    /**
     * Récupérer un utilisateur à partir de son addresse IP
     * @param ip Adresse IP de l'utilisateur que l'on souhaite retrouver
     * @return L'utilisateur associé à l'adresse IP
     * @throws Exception
     */
    public Utilisateur getIPList(InetAddress ip) throws Exception {
        for(Utilisateur elem: this.actifUsers)
        {
            if (elem.getIp().equals(ip) ) {
                return elem ;
            }
        }
        throw new Exception("No such user with this IP address") ;
    }

    /**
     * Récupérer un utilisateur à partir de son ID
     * @param iD L'ID de l'utilisateur que l'on souhaite retrouver
     * @return L'utilisateur associé à l'adresse ID
     * @throws Exception
     */
    public Utilisateur getIDList(String iD) throws Exception {
        for(Utilisateur elem: this.actifUsers)
        {
            if (elem.getId().equals(iD) ) {
                return elem ;
            }
        }
        throw new Exception("No such user with this ID") ;
    }

    /**
     * Supprimer de la liste des utilisateurs actifs 'actifUsers' un certain utilisateur
     * @param u On va supprimer cet utilisateur dans la liste
     */
    public void supprimerList(Utilisateur u) {
        boolean Sup = false ;
        for(Utilisateur elem: this.actifUsers)
        {
            if (elem.equals(u) ) {
                this.actifUsers.remove(elem);
                Sup = true ;
                this.afficherListeUtilisateurs();
                break;
            }
        }
        if (!Sup) {
            System.out.println("Tentative de retirer un objet non contenu dans la liste");
        }
    }

    /**
     * Modifier le pseudo d'un utilisateur dans la liste des utilisateurs actifs 'actifUsers'
     * @param ancien Pseudo à remplacer
     * @param nouveau Nouveau pseudo
     */
    public void modifierList(String ancien , String nouveau) {
        for(Utilisateur elem: this.actifUsers)
        {
            if (ancien.equals( elem.getPseudo() ) ) {
                this.actifUsers.remove(elem);
                elem.setPseudo(nouveau);
                this.addList(elem);
                break ;
            }
        }
        this.afficherListeUtilisateurs();
    }

    /**
     * Méthode permettant de savoir si un utilisateur est contenu dans la liste 'actifUsers'
     * @param u On souhaite savoir si cet utilisateur appartient a la liste
     * @return True si il appartient, False sinon
     */
    public Boolean appartient(Utilisateur u) {
        boolean appartient = false ;
        for(Utilisateur elem: this.actifUsers)
        {
            if (elem.equals(u) ) {
                appartient = true ;
                break;
            }
        }
        System.out.println("Test appartient : " + appartient);
        return appartient;
    }


    /**
     * Vérifie qu'aucun autre utilisateur ne posséde le meme pseudo
     * @param pseudo Pseudo dont on veut vérifier l'unicité
     * @return True si aucun utilisateur de la liste possède ce pseudo, False sinon
     */
    public Boolean verifierUnicite(String pseudo) {
        for(Utilisateur elem: this.actifUsers)
        {
            if (pseudo.equals( elem.getPseudo() ) ) {
                return false ;
            }
        }
        return true;
    }

    /**
     * Méthode affichant la liste des utilisateurs actifs
     */
    public void afficherListeUtilisateurs() {
        System.out.println ("Liste des utilisateurs actifs : ");
        StringBuilder Utilisateur = new StringBuilder();
        for(Utilisateur elem: this.actifUsers)
        {
            System.out.println (elem.toString());
            Utilisateur.append(elem).append("\n");
        }
    }

    /**
     * Getter : ActifUsers (liste des utilisateurs actifs)
     * @return La liste des utilisateurs actifs
     */
    public ArrayList<Utilisateur> getActifUsers(){
        return this.actifUsers;
    }
}
