package com.github.oxal;

import org.graphstream.algorithm.Toolkit;
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;
import org.graphstream.graph.implementations.DefaultGraph;
import org.graphstream.stream.file.FileSource;
import org.graphstream.stream.file.FileSourceEdge;

import java.io.IOException;
import java.util.Random;
import java.util.function.Consumer;

public class Epidemi {

    private Graph g;
    private Node origin;
    private Consumer<Node> infection;
    private Consumer<Node> soin;
    public static final String INFECTED = "infected";
    public static final Random random = new Random();

    public Epidemi(Graph g) {
        this.g = g;
    }

    public void init(Node n){
        origin = n;
    }

    public Consumer<Node> getInfection() {
        return infection;
    }

    public void setInfection(Consumer<Node> infection) {
        infection.accept(origin);
        this.infection = infection;
    }

    public Consumer<Node> getSoin() {
        return soin;
    }

    public void setSoin(Consumer<Node> soin) {
        this.soin = soin;
    }

    public void run(int t, double ratioEpi, double ratioSoin){
        for (int i = 0; i < t; i++){

            System.out.println(String.format("nombre d'infecter au jour %d : %d", i, g.getNodeSet()
                    .stream()
                    .filter(n -> n.hasAttribute(INFECTED) && n.<Boolean>getAttribute(INFECTED))
                    .count()
                    )
            );

            g.getNodeSet().forEach(n -> {
                double d = random.nextDouble();
                if (ratioEpi > d && n.hasAttribute(INFECTED) && n.<Boolean>getAttribute(INFECTED)){
                    n.getEdgeSet()
                            .forEach(e -> getInfection().accept(e.getOpposite(n)));
                }
            });


            g.getNodeSet().forEach(n -> {
                double d = random.nextDouble();
                if (ratioSoin > d){
                    getSoin().accept(n);
                }
            });

        }
    }

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

        fs.addSink(g);

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

        Epidemi epidemi = new Epidemi(g);
        epidemi.init(Toolkit.randomNode(g));
        epidemi.setInfection(n -> {
            if (random.nextInt(7) > 0){

            }
            n.setAttribute(INFECTED, true);
        });
        epidemi.setSoin(n -> {
            n.setAttribute(INFECTED, false);
        });

        epidemi.run(90, 1.0/7.0, 1.0/14.0);
    }
}
