use kube::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

pub fn sanitize_bouncer_name(input: &str) -> String {
    input
        .to_lowercase()
        .chars()
        .map(|c| if c.is_alphanumeric() || c == '-' { c } else { '-' })
        .collect::<String>()
        .trim_matches('-')
        .to_string()
}

// Minimal SojuBouncer spec -- just enough for the portal to create CRs.
// The full CRD is defined in the soju-operator crate.
#[derive(CustomResource, Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[kube(
    group = "irc.now",
    version = "v1alpha1",
    kind = "SojuBouncer",
    namespaced,
    status = "SojuBouncerStatus"
)]
pub struct SojuBouncerSpec {
    pub hostname: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub owner: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub hostname_cloak: Option<String>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
pub struct SojuBouncerStatus {
    #[serde(default)]
    pub conditions: Vec<SojuBouncerCondition>,
}

#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct SojuBouncerCondition {
    #[serde(rename = "type")]
    pub type_: String,
    pub status: String,
    #[serde(default)]
    pub reason: Option<String>,
    #[serde(default)]
    pub message: Option<String>,
}

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

    #[test]
    fn bouncer_name_sanitizes_input() {
        assert_eq!(sanitize_bouncer_name("My Bouncer!"), "my-bouncer");
        assert_eq!(sanitize_bouncer_name("test_123"), "test-123");
    }

    #[test]
    fn bouncer_name_trims_dashes() {
        assert_eq!(sanitize_bouncer_name("--hello--"), "hello");
    }

    #[test]
    fn bouncer_name_handles_empty() {
        assert_eq!(sanitize_bouncer_name(""), "");
    }
}
