package com.github.oxal;

import org.graphstream.algorithm.Dijkstra;
import org.graphstream.algorithm.Toolkit;
import org.graphstream.algorithm.generator.BarabasiAlbertGenerator;
import org.graphstream.algorithm.generator.Generator;
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;
import org.graphstream.graph.Path;
import org.graphstream.graph.implementations.DefaultGraph;
import org.graphstream.graph.implementations.SingleGraph;
import org.graphstream.stream.file.FileSource;
import org.graphstream.stream.file.FileSourceEdge;

import java.io.*;
import java.util.ArrayList;
import java.util.Collection;

public class Main {

    public static void main(String[] args) {
        String filePath = "src/main/resources/graph.txt";
        Graph g = new DefaultGraph("g");
        FileSource fs = new FileSourceEdge();

        fs.addSink(g);

        try {
            fs.readAll(filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //nb de node
        System.out.println("nb node " + g.getNodeCount());

        //nb de edge
        System.out.println("nb edge " + g.getEdgeCount());


        //moyenne de degré
        System.out.println("moy degre " + Toolkit.averageDegree(g));

        /**
         *
         System.out.println(g.getNodeSet()
         .stream()
         .mapToDouble(n -> n.getDegree())
         .average()
         .getAsDouble()
         );
         */

        //coef cluster
        System.out.println("coef cluster " + Toolkit.averageClusteringCoefficient(g));


        //connexe
        System.out.println("connexe " + Toolkit.isConnected(g));


        try {
            BufferedWriter writer = new BufferedWriter(new FileWriter("degres.txt"));
            int[] dd = Toolkit.degreeDistribution(g);
            for (int k = 0; k < dd.length; k++) {
                if (dd[k] != 0) {

                    String str = String.format("%d\t%f\n", k, (double)dd[k] / g.getNodeCount()).replace(",", ".");
                    writer.write(str);
                }
            }
            writer.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }



        Collection<Node> list = Toolkit.randomNodeSet(g, 1000);

        Dijkstra dij = new Dijkstra();
        dij.init(g);

        ArrayList<Integer> countLength = new ArrayList<>();

        Node n1 = Toolkit.randomNode(g);
        dij.setSource(n1);
        dij.compute();

        for (Node n2 : list){
            if (n1 != n2){
                Path path = dij.getPath(n2);
                countLength.add(path.getEdgeSet().size());
            }
        }

        System.out.println(countLength.stream().mapToDouble(Integer::doubleValue).average());


        Graph graph = new SingleGraph("stat");
        Generator gen = new BarabasiAlbertGenerator((int) Toolkit.averageDegree(g));
        gen.addSink(graph);
        gen.begin();
        for(int i=0; i<g.getNodeCount(); i++)
            gen.nextEvents();
        gen.end();


        System.out.println(graph.getEdgeCount());
        System.out.println(Toolkit.averageDegree(graph));
        System.out.println("coef cluster " + Toolkit.averageClusteringCoefficient(graph));
        System.out.println("connexe " + Toolkit.isConnected(graph));


        Collection<Node> list2 = Toolkit.randomNodeSet(graph, 1000);
        ArrayList<Integer> countLength2 = new ArrayList<>();

        Dijkstra dij2 = new Dijkstra();
        dij2.init(graph);
        Node n2 = Toolkit.randomNode(graph);
        dij2.setSource(n2);
        dij2.compute();

        for (Node n3 : list2){
            if (n2 != n3){
                Path path = dij2.getPath(n3);
                countLength2.add(path.getEdgeSet().size());
            }
        }

        System.out.println(countLength2.stream().mapToDouble(Integer::doubleValue).average());
    }
}
