//! Tests for transport-specific `BotConfig` loading: WhatsApp, Twilio, Slack, Discord.
use super::*;
use std::fs;

#[test]
fn load_transport_reads_custom_value() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
room_ids = ["!abc:example.com"]
enabled = true
transport = "whatsapp"
whatsapp_phone_number_id = "123456"
whatsapp_access_token = "EAAtoken"
whatsapp_verify_token = "my-verify"
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.transport, "whatsapp");
    assert_eq!(config.whatsapp_phone_number_id.as_deref(), Some("123456"));
    assert_eq!(config.whatsapp_access_token.as_deref(), Some("EAAtoken"));
    assert_eq!(config.whatsapp_verify_token.as_deref(), Some("my-verify"));
}

#[test]
fn load_whatsapp_returns_none_when_missing_phone_number_id() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "whatsapp"
whatsapp_access_token = "EAAtoken"
whatsapp_verify_token = "my-verify"
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

#[test]
fn load_whatsapp_returns_none_when_missing_access_token() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "whatsapp"
whatsapp_phone_number_id = "123456"
whatsapp_verify_token = "my-verify"
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

#[test]
fn load_whatsapp_returns_none_when_missing_verify_token() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "whatsapp"
whatsapp_phone_number_id = "123456"
whatsapp_access_token = "EAAtoken"
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

// ── Twilio config tests ─────────────────────────────────────────────

#[test]
fn load_twilio_whatsapp_reads_config() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "whatsapp"
whatsapp_provider = "twilio"
twilio_account_sid = "ACtest"
twilio_auth_token = "authtest"
twilio_whatsapp_number = "+14155551234"
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.transport, "whatsapp");
    assert_eq!(config.whatsapp_provider, "twilio");
    assert_eq!(config.twilio_account_sid.as_deref(), Some("ACtest"));
    assert_eq!(config.twilio_auth_token.as_deref(), Some("authtest"));
    assert_eq!(
        config.twilio_whatsapp_number.as_deref(),
        Some("+14155551234")
    );
}

#[test]
fn load_whatsapp_provider_defaults_to_meta() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "whatsapp"
whatsapp_phone_number_id = "123456"
whatsapp_access_token = "EAAtoken"
whatsapp_verify_token = "my-verify"
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.whatsapp_provider, "meta");
}

#[test]
fn load_twilio_returns_none_when_missing_account_sid() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "whatsapp"
whatsapp_provider = "twilio"
twilio_auth_token = "authtest"
twilio_whatsapp_number = "+14155551234"
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

#[test]
fn load_twilio_returns_none_when_missing_auth_token() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "whatsapp"
whatsapp_provider = "twilio"
twilio_account_sid = "ACtest"
twilio_whatsapp_number = "+14155551234"
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

#[test]
fn load_twilio_returns_none_when_missing_whatsapp_number() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "whatsapp"
whatsapp_provider = "twilio"
twilio_account_sid = "ACtest"
twilio_auth_token = "authtest"
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

// ── Slack config tests ─────────────────────────────────────────────

#[test]
fn load_slack_transport_reads_config() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "slack"
slack_bot_token = "xoxb-123"
slack_signing_secret = "secret123"
slack_channel_ids = ["C01ABCDEF"]
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.transport, "slack");
    assert_eq!(config.slack_bot_token.as_deref(), Some("xoxb-123"));
    assert_eq!(config.slack_signing_secret.as_deref(), Some("secret123"));
    assert_eq!(config.slack_channel_ids, vec!["C01ABCDEF"]);
}

#[test]
fn load_slack_returns_none_when_missing_bot_token() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "slack"
slack_signing_secret = "secret123"
slack_channel_ids = ["C01ABCDEF"]
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

#[test]
fn load_slack_returns_none_when_missing_signing_secret() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "slack"
slack_bot_token = "xoxb-123"
slack_channel_ids = ["C01ABCDEF"]
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

#[test]
fn load_slack_returns_none_when_missing_channel_ids() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
enabled = true
transport = "slack"
slack_bot_token = "xoxb-123"
slack_signing_secret = "secret123"
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

#[test]
fn whatsapp_allowed_phones_defaults_to_empty_when_absent() {
    let config: BotConfig = toml::from_str(
        r#"
enabled = true
transport = "whatsapp"
whatsapp_provider = "meta"
whatsapp_phone_number_id = "123"
whatsapp_access_token = "tok"
whatsapp_verify_token = "ver"
"#,
    )
    .unwrap();
    assert!(config.whatsapp_allowed_phones.is_empty());
}

#[test]
fn whatsapp_allowed_phones_deserializes_list() {
    let config: BotConfig = toml::from_str(
        r#"
enabled = true
transport = "whatsapp"
whatsapp_provider = "meta"
whatsapp_phone_number_id = "123"
whatsapp_access_token = "tok"
whatsapp_verify_token = "ver"
whatsapp_allowed_phones = ["+15551234567", "+15559876543"]
"#,
    )
    .unwrap();
    assert_eq!(
        config.whatsapp_allowed_phones,
        vec!["+15551234567", "+15559876543"]
    );
}

// ── Discord config tests ──────────────────────────────────────────

#[test]
fn load_discord_transport_reads_config() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
enabled = true
transport = "discord"
discord_bot_token = "Bot.Token.Here"
discord_channel_ids = ["123456789012345678"]
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.transport, "discord");
    assert_eq!(config.discord_bot_token.as_deref(), Some("Bot.Token.Here"));
    assert_eq!(config.discord_channel_ids, vec!["123456789012345678"]);
}

#[test]
fn load_discord_returns_none_when_missing_bot_token() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
enabled = true
transport = "discord"
discord_channel_ids = ["123456789012345678"]
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

#[test]
fn load_discord_returns_none_when_missing_channel_ids() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(
        sk.join("bot.toml"),
        r#"
enabled = true
transport = "discord"
discord_bot_token = "Bot.Token.Here"
"#,
    )
    .unwrap();
    assert!(BotConfig::load(tmp.path()).is_none());
}

#[test]
fn discord_allowed_users_defaults_to_empty_when_absent() {
    let config: BotConfig = toml::from_str(
        r#"
enabled = true
transport = "discord"
discord_bot_token = "Bot.Token.Here"
discord_channel_ids = ["123456789"]
"#,
    )
    .unwrap();
    assert!(config.discord_allowed_users.is_empty());
}

#[test]
fn discord_allowed_users_deserializes_list() {
    let config: BotConfig = toml::from_str(
        r#"
enabled = true
transport = "discord"
discord_bot_token = "Bot.Token.Here"
discord_channel_ids = ["123456789"]
discord_allowed_users = ["111222333", "444555666"]
"#,
    )
    .unwrap();
    assert_eq!(config.discord_allowed_users, vec!["111222333", "444555666"]);
}
