use crate::fact::MemoFact;

pub struct CrystallizedKnowledge {
    facts: Vec<MemoFact>,
}

impl CrystallizedKnowledge {
    pub fn new() -> Self {
        Self { facts: Vec::new() }
    }

    pub fn insert(&mut self, fact: MemoFact) {
        // Supersession: remove old fact with same key
        if let Some(sup) = &fact.supersedes {
            self.facts.retain(|f| &f.id != sup);
        }
        self.facts.push(fact);
    }

    pub fn search(&self, keyword: &str) -> Vec<MemoFact> {
        let kw = keyword.to_lowercase().replace(['-', '_', '.'], " ");
        self.facts
            .iter()
            .filter(|f| {
                f.key
                    .to_lowercase()
                    .replace(['-', '_', '.'], " ")
                    .contains(&kw)
                    || f.value
                        .to_lowercase()
                        .replace(['-', '_', '.'], " ")
                        .contains(&kw)
            })
            .cloned()
            .collect()
    }

    pub fn all(&self) -> &[MemoFact] {
        &self.facts
    }
    pub fn facts_mut(&mut self) -> &mut Vec<MemoFact> {
        &mut self.facts
    }
    pub fn len(&self) -> usize {
        self.facts.len()
    }
    pub fn is_empty(&self) -> bool {
        self.facts.is_empty()
    }
}

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