//! Parsed `extension.yaml` manifest.

use serde::Deserialize;

pub(crate) fn parse_manifest(yaml: &str) -> crate::prelude::Result<ExtensionManifest> {
    let manifest: ExtensionManifest = serde_saphyr::from_str(yaml)?;
    Ok(manifest)
}

#[derive(Debug, Clone, Deserialize)]
pub(crate) struct ExtensionManifest {
    pub name: String,
    pub version: String,
    #[serde(default)]
    #[allow(dead_code)]
    pub description: String,
    #[serde(default)]
    #[allow(dead_code)]
    pub repo: String,
    #[allow(dead_code)]
    pub ide_api_version: String,
    #[allow(dead_code)]
    pub wasm: String,
    #[serde(default)]
    pub commands: Vec<CommandSpec>,
    #[serde(default)]
    pub events: Vec<String>,
    #[serde(default)]
    pub schemas: Option<Vec<SchemaManifestEntry>>,
    #[serde(default)]
    pub log_matchers: Vec<crate::log_matcher::LogMatcherDef>,
}

#[derive(Debug, Clone, Deserialize)]
pub(crate) struct CommandSpec {
    pub id: String,
    pub title: String,
    #[serde(default)]
    pub description: String,
    /// Name of the WASM exported function (without the `__oo_cmd_` prefix).
    pub function: String,
    /// oo context tag required for this command to appear (empty = always).
    #[serde(default)]
    pub activation_context: String,
}

#[derive(Debug, Clone, Deserialize)]
pub(crate) struct SchemaManifestEntry {
    pub schema: String,
    #[serde(default)]
    pub patterns: Vec<String>,
}

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------

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

    #[test]
    fn parse_minimal_manifest() {
        let yaml = r#"
name: test-ext
version: "0.1.0"
ide_api_version: "0.1"
wasm: extension.wasm
commands:
  - id: test.hello
    title: Hello
    function: cmd_hello
events:
  - project_opened
"#;
        let manifest = parse_manifest(yaml).expect("should parse");
        assert_eq!(manifest.name, "test-ext");
        assert_eq!(manifest.commands.len(), 1);
        assert_eq!(manifest.commands[0].function, "cmd_hello");
        assert_eq!(manifest.events, ["project_opened"]);
    }
}


