package impl;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.Future;

import interfaces.AlgoDiffusion;
import interfaces.ObserverDeCapteurAsync;

public class DiffusionAtomique implements AlgoDiffusion {

    public CapteurImpl capteur;
    private List<Future<?>> futures;
    private Queue<Integer> values;


    public DiffusionAtomique(CapteurImpl c){
        this.capteur = c;
        this.futures = new ArrayList<Future<?>>();
        this.values = new ArrayDeque<>();

    }

    @Override
    public int getValue() {
        return this.values.peek();
    }

    @Override
    public void execute() {
        System.out.println("execute");

        if(!this.capteur.isStop()){
            this.values.offer(this.capteur.getValue());
        }

        if(!this.futures.isEmpty()){
            //vérification si les Futures sont finis
            this.futures.removeIf(Future::isDone);
            if(this.futures.isEmpty()){
                this.values.remove();
                System.out.println("next value");
            }
        }

        // si futures est empty, alors tous les Future des canaux précédents sont finis
        // et on peut relancer des futures sans attendre le prochain ticket, pour ne pas accumuler encore plus de retard
        if(this.futures.isEmpty()){
            if(!this.values.isEmpty()){ //le capteur ne répond pas (car stopé ici)
                for (ObserverDeCapteurAsync canal : capteur.observers) {
                    Future<?> f = canal.update();
                    this.futures.add(f);
                }
            }
        }
    }
}
