package fr.univ.dblp.utils;

import org.graphstream.algorithm.Toolkit;
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Utilitaire pour l'échantillonnage aléatoire de nœuds.
 *
 * Cette classe permet de sélectionner aléatoirement des nœuds d'un graphe,
 * utile pour les analyses sur de grands réseaux où il n'est pas possible
 * de traiter tous les nœuds.
 *
 * @author Hamadou BA
 * @see <a href="https://www-apps.univ-lehavre.fr/forge/bh243413/tp2-ri-mesures-de-reseaux-interaction.git">Dépôt Git</a>
 */
public class RandomSampler {

    /**
     * Échantillonne aléatoirement un nombre spécifié de nœuds du graphe.
     *
     * Cette méthode garantit que chaque nœud n'est sélectionné qu'une seule fois
     * (échantillonnage sans remise).
     *
     * @param g Le graphe dont on extrait les nœuds
     * @param sampleSize Nombre de nœuds à échantillonner
     * @return Liste des nœuds échantillonnés aléatoirement
     * @throws IllegalArgumentException si sampleSize dépasse le nombre de nœuds
     */
    public static List<Node> sampleNodes(Graph g, int sampleSize) {
        if (sampleSize > g.getNodeCount()) {
            throw new IllegalArgumentException(
                "Sample size cannot exceed number of nodes");
        }

        Set<String> sampledIds = new HashSet<>();
        List<Node> sampledNodes = new ArrayList<>();

        while (sampledNodes.size() < sampleSize) {
            Node node = Toolkit.randomNode(g);
            if (node != null && !sampledIds.contains(node.getId())) {
                sampledIds.add(node.getId());
                sampledNodes.add(node);
            }
        }

        return sampledNodes;
    }

    /**
     * Retourne un nœud aléatoire du graphe.
     *
     * @param g Le graphe
     * @return Un nœud choisi aléatoirement
     */
    public static Node getRandomNode(Graph g) {
        return Toolkit.randomNode(g);
    }
}
