use crate::{
    N_INF,
    drift::{ConstantDrift, Drift},
    gaussian::Gaussian,
    player::Player,
};

#[derive(Debug)]
pub struct Agent<D: Drift = ConstantDrift> {
    pub player: Player<D>,
    pub message: Gaussian,
    pub last_time: i64,
}

impl<D: Drift> Agent<D> {
    pub(crate) fn receive(&self, elapsed: i64) -> Gaussian {
        if self.message != N_INF {
            self.message
                .forget(self.player.drift.variance_delta(elapsed))
        } else {
            self.player.prior
        }
    }
}

impl Default for Agent<ConstantDrift> {
    fn default() -> Self {
        Self {
            player: Player::default(),
            message: N_INF,
            last_time: i64::MIN,
        }
    }
}

pub(crate) fn clean<'a, D: Drift + 'a, A: Iterator<Item = &'a mut Agent<D>>>(
    agents: A,
    last_time: bool,
) {
    for a in agents {
        a.message = N_INF;

        if last_time {
            a.last_time = i64::MIN;
        }
    }
}
