package org.example;

import org.graphstream.graph.BreadthFirstIterator;
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import java.util.Map;

import static org.example.GraphManipulation.*;
import static org.example.Gnuplot.*;
public class Main {
    public static void main(String[] args) {
     System.setProperty("org.graphstream.ui", "swing");
        String path = "src/main/resources/com-dblp.ungraph.txt";
        Graph graph = getTheFileEdge(path);
        int nodeCount = getNodeCount(graph);
        System.out.println("=============== Graphe Exemple DBLP ===============");
        System.out.println("Nombre de noeuds : " + nodeCount);
        System.out.println("Nombre d'arêtes : " +getEdgeCount(graph));
        double averageDegree = getAverageDegree(graph) ;
        System.out.println("Degré Moyen : "+averageDegree);
        System.out.println("Coefficient de clustering : " + getAverageClusteringCoefficient(graph));
        System.out.println("Coefficient de clustering attendu (graphe aléatoire) : "+getRandomGraphClustering(averageDegree,nodeCount));
        System.out.println("Graphe connexe : "+isConnexe(graph));
        System.out.println("Graphe orienté : "+isOrientedGraph(graph));
        getDegreeDistribution(graph);

        analyzeDistances(graph, 1000, "src/main/gnuplot/averageDistanceOf1000Node.dat");

        System.out.println("=============== Graphe Random ===============");

        Graph randomGraph = GraphGenerator.generateRandomGraph(nodeCount,averageDegree);
        System.out.println("Nombre d'arêtes : " +getEdgeCount(randomGraph));
        System.out.println("Degré Moyen : "+getAverageDegree(randomGraph));
        System.out.println("Coefficient de clustering : " + getAverageClusteringCoefficient(randomGraph));
        System.out.println("Graphe connexe : "+isConnexe(randomGraph));
        System.out.println("Graphe orienté : "+isOrientedGraph(randomGraph));
        analyzeDistances(randomGraph, 1000, "src/main/gnuplot/averageDistanceOf1000NodeForRandomGraph.dat");

        System.out.println("=============== Graphe BarabasiAlbert ===============");
        Graph barabasiAlbertGraph = GraphGenerator.generateBarabasiAlbertGraph(nodeCount,averageDegree);
        System.out.println("Nombre d'arêtes : " +getEdgeCount(barabasiAlbertGraph));
        System.out.println("Degré Moyen : "+getAverageDegree(barabasiAlbertGraph));
        System.out.println("Coefficient de clustering : " + getAverageClusteringCoefficient(barabasiAlbertGraph));
        System.out.println("Graphe connexe : "+isConnexe(barabasiAlbertGraph));
        System.out.println("Graphe orienté : "+isOrientedGraph(barabasiAlbertGraph));

        analyzeDistances(barabasiAlbertGraph, 1000, "src/main/gnuplot/averageDistanceOf1000NodeForBarabasiAlbertGraph.dat");
    }

    public static void analyzeDistances(Graph graph, int numberOfNodes, String filePath) {
        Map<Integer, Double> mapProba = getDistanceProbabilities(getProbaDistanceOfNNode(numberOfNodes, graph));

        List<Integer> distances = new ArrayList<>(mapProba.keySet());
        List<Double> probabilites = new ArrayList<>(mapProba.values());
        List<List<?>> combined = new ArrayList<>();
        combined.add(distances);
        combined.add(probabilites);

        System.out.println("Probabilités des distances : " + mapProba);
        try {
            saveDatMultipleList(filePath, combined);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Affichage de la distance moyenne
        double avgDistance = GraphManipulation.getAverageDistanceOfNNode(numberOfNodes, graph);
        System.out.println("Distance moyenne pour " + numberOfNodes + " nœuds : " + avgDistance);
    }
}