//! `[[streams]]` TOML config block parsed from `dirigent.toml`.

use serde::{Deserialize, Serialize};
use dirigent_protocol::streaming::StreamScope;

#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct StreamsConfig {
    #[serde(default, rename = "streams")]
    pub entries: Vec<StreamConfig>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct StreamConfig {
    pub name: String,
    #[serde(rename = "type")]
    pub kind: String,               // "matrix" | "langfuse" | ...
    pub scope: StreamScope,
    #[serde(default = "default_enabled")]
    pub enabled: bool,
    #[serde(default = "default_params")]
    pub params: toml::Value,        // type-specific
}

fn default_enabled() -> bool { true }

fn default_params() -> toml::Value { toml::Value::Table(toml::map::Map::new()) }

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

    const FULL_TOML: &str = r#"
[[streams]]
name = "matrix-main"
type = "matrix"
enabled = true

[streams.scope]
kind = "session"
scroll_id = "01985d00-0000-7000-8000-000000000000"

[streams.params]
homeserver_url = "https://matrix.org"
room_id = "!abc:matrix.org"
"#;

    const MINIMAL_TOML: &str = r#"
[[streams]]
name = "minimal"
type = "langfuse"

[streams.scope]
kind = "archive_wide"
acknowledged = false
"#;

    #[test]
    fn round_trip_full() {
        let cfg: StreamsConfig = toml::from_str(FULL_TOML).expect("parse failed");

        assert_eq!(cfg.entries.len(), 1);
        let entry = &cfg.entries[0];
        assert_eq!(entry.name, "matrix-main");
        assert_eq!(entry.kind, "matrix");
        assert!(entry.enabled);

        let expected_id = Uuid::parse_str("01985d00-0000-7000-8000-000000000000").unwrap();
        match &entry.scope {
            StreamScope::Session { scroll_id } => {
                assert_eq!(*scroll_id, expected_id);
            }
            other => panic!("expected Session scope, got {:?}", other),
        }

        let params = entry.params.as_table().expect("params should be a table");
        assert_eq!(
            params.get("homeserver_url").and_then(|v| v.as_str()),
            Some("https://matrix.org")
        );
        assert_eq!(
            params.get("room_id").and_then(|v| v.as_str()),
            Some("!abc:matrix.org")
        );
    }

    #[test]
    fn default_enabled_when_omitted() {
        let cfg: StreamsConfig = toml::from_str(MINIMAL_TOML).expect("parse failed");
        assert_eq!(cfg.entries.len(), 1);
        let entry = &cfg.entries[0];
        assert_eq!(entry.name, "minimal");
        assert!(entry.enabled, "enabled should default to true");
    }

    #[test]
    fn empty_config_is_valid() {
        let cfg: StreamsConfig = toml::from_str("").expect("empty parse failed");
        assert!(cfg.entries.is_empty());
    }
}
