package org.example;

import org.graphstream.algorithm.Toolkit;
import org.graphstream.graph.*;
import org.graphstream.graph.implementations.*;
import org.graphstream.stream.file.FileSourceEdge;

import java.io.FileWriter;
import java.util.HashMap;
import java.util.Map;

public class DBLPNetworkAnalysis {
    public static void main(String[] args) throws Exception {
        String filePath = "/home/c2i/IdeaProjects/TP_RI/com-dblp.ungraph.txt"; // Chemin du fichier d'entrée
        Graph graph = new SingleGraph("Réseau de collaboration DBLP");

        // Chargement des données
        FileSourceEdge fileSource = new FileSourceEdge();
        fileSource.addSink(graph);

        try {
            fileSource.readAll(filePath);
        } finally {
            fileSource.removeSink(graph);
        }

        // Mesures de base
        int nodeCount = graph.getNodeCount();  // Nombre de nœuds
        int edgeCount = graph.getEdgeCount();  // Nombre de liens
        double averageDegree = Toolkit.averageDegree(graph);  // Degré moyen
        double clusteringCoefficient = Toolkit.averageClusteringCoefficient(graph);  // Coefficient de clustering réel
        double randomClusteringCoefficient = averageDegree / nodeCount;  // Coefficient de clustering aléatoire
        boolean isConnected = Toolkit.isConnected(graph);  // Connexité
        double minAverageDegreeForConnectivity = Math.log(nodeCount);  // Degré moyen minimal pour un graphe connexe

        // Affichage des résultats
        System.out.println("Nombre de nœuds : " + nodeCount);
        System.out.println("Nombre de liens : " + edgeCount);
        System.out.println("Degré moyen : " + averageDegree);
        System.out.println("Coefficient de clustering (réel) : " + clusteringCoefficient);
        System.out.println("Coefficient de clustering (aléatoire) : " + randomClusteringCoefficient);
        System.out.println("Le réseau est-il connexe ? : " + (isConnected ? "Oui" : "Non"));
        System.out.println("Degré moyen minimal pour qu'un graphe aléatoire soit connexe : " + minAverageDegreeForConnectivity);

        // Calcul et enregistrement de la distribution des degrés
        DegreeDistribution.calculerDistributionDeDegrés(graph, "distribution_de_degres.csv");
    }

    public static class DegreeDistribution {
        public static void calculerDistributionDeDegrés(Graph graph, String fichierSortie) throws Exception {
            Map<Integer, Integer> compteDeDegrés = new HashMap<>();
            int nodeCount = graph.getNodeCount();

            // Calcul des degrés et de leur fréquence
            for (Node node : graph) {
                int degree = node.getDegree();
                compteDeDegrés.put(degree, compteDeDegrés.getOrDefault(degree, 0) + 1);
            }

            // Calcul des probabilités de chaque degré
            try (FileWriter writer = new FileWriter(fichierSortie)) {
                writer.write("Degré\tProbabilité\n");  // Entête du fichier CSV
                for (Map.Entry<Integer, Integer> entry : compteDeDegrés.entrySet()) {
                    int degree = entry.getKey();
                    int count = entry.getValue();
                    double probabilité = (double) count / nodeCount;  // Calcul de la probabilité
                    writer.write(degree + "\t" + probabilité + "\n");
                }
            }

            System.out.println("Distribution des degrés (avec probabilités) enregistrée dans : " + fichierSortie);
        }
    }
}
