use crate::config::NatsAdminNamespaceConfig;

/// Builds fully-qualified NATS subject paths from a namespace config and leaf
/// subject names.
///
/// Full subject: `{prefix}.{env}.{leaf}`
/// e.g. `evol.website.prod.admin.logs`
///
/// The leaf names come from `NatsAdminConnectionConfig::subjects` — an open map
/// so implementations can extend them without touching framework code.
#[derive(Debug, Clone)]
pub struct SubjectBuilder {
    prefix: String,
    env: String,
}

impl SubjectBuilder {
    pub fn new(namespace: &NatsAdminNamespaceConfig) -> Self {
        Self {
            prefix: namespace.prefix.clone(),
            env: namespace.env.clone(),
        }
    }

    /// Build a full subject from a leaf name stored in the config subjects map.
    ///
    /// Returns `None` if the leaf key is not present in the map.
    pub fn build_from_map(
        &self,
        subjects: &std::collections::HashMap<String, String>,
        key: &str,
    ) -> Option<String> {
        subjects.get(key).map(|leaf| self.build(leaf))
    }

    /// Build a full subject from an explicit leaf string.
    pub fn build(&self, leaf: &str) -> String {
        format!("{}.{}.{}", self.prefix, self.env, leaf)
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;

    use super::*;

    fn make_builder() -> SubjectBuilder {
        SubjectBuilder {
            prefix: "evol.website".to_string(),
            env: "prod".to_string(),
        }
    }

    #[test]
    fn build_full_subject() {
        let b = make_builder();
        assert_eq!(b.build("admin.logs"), "evol.website.prod.admin.logs");
    }

    #[test]
    fn build_from_map_found() {
        let b = make_builder();
        let mut m = HashMap::new();
        m.insert("logs".to_string(), "admin.logs".to_string());
        assert_eq!(
            b.build_from_map(&m, "logs"),
            Some("evol.website.prod.admin.logs".to_string())
        );
    }

    #[test]
    fn build_from_map_missing() {
        let b = make_builder();
        let m = HashMap::new();
        assert!(b.build_from_map(&m, "nonexistent").is_none());
    }
}
