use std::sync::OnceLock;

use super::ToolDef;

const BUILTIN_TOMLS: &[(&str, &str)] = &[("claude", include_str!("data/claude.toml"))];

static CACHE: OnceLock<Vec<ToolDef>> = OnceLock::new();

fn parsed() -> &'static Vec<ToolDef> {
    CACHE.get_or_init(|| {
        BUILTIN_TOMLS
            .iter()
            .map(|(slot, text)| {
                let tool: ToolDef = toml::from_str(text)
                    .unwrap_or_else(|e| panic!("built-in tool '{slot}' invalid: {e}"));
                assert_eq!(
                    tool.name, *slot,
                    "built-in {slot}.toml name field does not match filename"
                );
                tool
            })
            .collect()
    })
}

pub fn all() -> Vec<ToolDef> {
    parsed().clone()
}

pub fn by_name(name: &str) -> Option<ToolDef> {
    parsed().iter().find(|t| t.name == name).cloned()
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::registry::Artifact;
    use crate::tools::Tool;

    #[test]
    fn all_builtins_parse() {
        assert_eq!(all().len(), BUILTIN_TOMLS.len());
    }

    #[test]
    fn claude_tool_has_curl_install_and_update() {
        let t = by_name("claude").expect("claude built-in tool");
        assert_eq!(t.runtime, Some(Tool::Claude));
        assert!(t.install.iter().any(|m| m.command.contains("install.sh")));
        assert_eq!(t.update.as_deref(), Some("claude update"));
        assert!(matches!(
            &t.artifacts[0],
            Artifact::Cli { name } if name == "claude"
        ));
    }
}
