use crate::fact::MemoFact;

pub struct PhantomSlot {
    pub fact: MemoFact,
    pub eviction_score: f32,
}

pub struct PhantomCache {
    slots: Vec<PhantomSlot>,
    max_slots: usize,
}

impl PhantomCache {
    pub fn new(max_slots: usize) -> Self {
        Self {
            slots: Vec::new(),
            max_slots,
        }
    }

    pub fn insert(&mut self, fact: MemoFact) {
        if self.slots.len() >= self.max_slots {
            // Evict lowest score
            if let Some(min_idx) = self
                .slots
                .iter()
                .enumerate()
                .min_by(|a, b| a.1.eviction_score.partial_cmp(&b.1.eviction_score).unwrap())
                .map(|(i, _)| i)
            {
                self.slots.remove(min_idx);
            }
        }
        self.slots.push(PhantomSlot {
            eviction_score: fact.confidence,
            fact,
        });
    }

    pub fn len(&self) -> usize {
        self.slots.len()
    }
    pub fn is_empty(&self) -> bool {
        self.slots.is_empty()
    }
}

impl Default for PhantomCache {
    fn default() -> Self {
        Self::new(64)
    }
}
