use anyhow::{bail, Result};
use rand::Rng;
use std::collections::HashSet;

pub fn generate_hash(existing: &HashSet<String>) -> Result<String> {
    let mut rng = rand::thread_rng();
    for _ in 0..10 {
        let hash = format!("{:04x}", rng.gen_range(0..0x10000u32));
        if !existing.contains(&hash) {
            return Ok(hash);
        }
    }
    bail!("Failed to generate unique hash after 10 attempts")
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_generate_hash() {
        let existing = HashSet::new();
        let hash = generate_hash(&existing).unwrap();
        assert_eq!(hash.len(), 4);
        assert!(hash.chars().all(|c| c.is_ascii_hexdigit()));
    }

    #[test]
    fn test_no_collision() {
        let mut existing = HashSet::new();
        existing.insert("abcd".to_string());
        let hash = generate_hash(&existing).unwrap();
        assert_ne!(hash, "abcd");
    }
}
