package rh213424;

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

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;

import static org.graphstream.algorithm.Toolkit.averageDegree;

public class Propagation {
    /**
     * graphe du réseau
     */
    private Graph graph;

    public Propagation(Graph graph) {
        this.graph = graph;
    }
    /**
     * calcul la distribution des degrés <k²>
     * @return double
     */
    public  double  distributionDegre(){
        double d = 0.0;
        int[] tabDistributionDegres= Toolkit.degreeDistribution(graph);
        for (int i = 0; i < tabDistributionDegres.length; i++) {
            double moyenneDegre = (double) tabDistributionDegres[i] / graph.getNodeCount();
            if (tabDistributionDegres[i] > 0) {
                d += Math.pow(i, 2) * moyenneDegre;
            }
        }
        return d;
    }

    /**
     * Calcul du taux de propagation λ = β / μ
     */
    public static void tauxPropagation(){
        double beta = 1.0/7.0;
        double gama = 1.0/14.0;
        double taux = beta/gama;
        System.out.println("Le taux de propagation du virus est : "+taux);
    }

    /**
     * Calcule et affiche le seuil épidémique
     */
    public void seuilEpidemique(){
        double k2 = distributionDegre();
        System.out.println("La distribution des degrés <k²> de notre réseau est :"+k2);
        double k = averageDegree(graph);
        double seuil = k/k2;
        System.out.println("Le seuil épidémique du réseau est : "+seuil);
    }

    /**
     * Simulation premier scenario
     */
    public void scenario1() throws IOException {
        int jours = 90;
        StringBuilder data = new StringBuilder();
        Node patient0 = Toolkit.randomNode(graph);
        patient0.setAttribute("santé","infecté");
        LinkedList<Node> infectes = new LinkedList<>();
        infectes.add(patient0);
        Random random = new Random();
        for(int jour=1;jour<=jours;jour++){
            int jourInfection = 1;
            int nbrInfecteJour = 1;
            for(Node n : graph){
                if(n.getAttribute("santé") == "infecté") {
                    //probabilité de 1/7
                    if(random.nextInt(8) == jourInfection) {
                        for(Edge e : n){
                            Node collaborateur = e.getOpposite(n);
                            collaborateur.setAttribute("santé", "infecté");
                            infectes.add(collaborateur);
                            nbrInfecteJour++;
                        }
                    }
                    //mise à jour de l'antivirus avec probabilité de 1/14
                    int jourImmunisation = 2;
                    if (random.nextInt(15) == jourImmunisation) {
                        if(n.getAttribute("santé")=="infecté"){
                            n.setAttribute("santé", "sain");
                            nbrInfecteJour-=1;
                        }
                    }
                }
            }
            System.out.println(jour +" "+nbrInfecteJour);
            data.append(jour).append(" ").append(nbrInfecteJour).append(System.getProperty("line.separator"));
        }
        ecrireDataFichier(data,1);
    }

    /**
     * Méthode pour l'écriture des données pour chaque scénario
     * @param data
     * @param nbrSce
     * @throws IOException
     */
    public void ecrireDataFichier(StringBuilder data,int nbrSce) throws IOException {
        BufferedWriter writer = new BufferedWriter(new FileWriter("Scénario "+nbrSce));
        writer.write(String.valueOf(data));
        writer.close();
    }
    /**
     * Simulation scénario2
     */
    public void scenario2(){

    }
}
