//! Tests for core `BotConfig` loading: matrix transport, ambient rooms, history, timeouts.
use super::*;
use std::fs;

#[test]
fn load_returns_none_when_file_missing() {
    let tmp = tempfile::tempdir().unwrap();
    let result = BotConfig::load(tmp.path());
    assert!(result.is_none());
}

#[test]
fn load_returns_none_when_disabled() {
    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 = false
"#,
    )
    .unwrap();
    let result = BotConfig::load(tmp.path());
    assert!(result.is_none());
}

#[test]
fn load_returns_config_when_enabled_with_room_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"
room_ids = ["!abc:example.com", "!def:example.com"]
enabled = true
"#,
    )
    .unwrap();
    let result = BotConfig::load(tmp.path());
    assert!(result.is_some());
    let config = result.unwrap();
    assert_eq!(
        config.homeserver.as_deref(),
        Some("https://matrix.example.com")
    );
    assert_eq!(config.username.as_deref(), Some("@bot:example.com"));
    assert_eq!(
        config.effective_room_ids(),
        &["!abc:example.com", "!def:example.com"]
    );
    assert!(config.model.is_none());
}

#[test]
fn load_merges_deprecated_room_id_into_room_ids() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    // Old-style single room_id key — should still work.
    fs::write(
        sk.join("bot.toml"),
        r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
room_id = "!abc:example.com"
enabled = true
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.effective_room_ids(), &["!abc:example.com"]);
}

#[test]
fn load_returns_none_when_no_room_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
"#,
    )
    .unwrap();
    let result = BotConfig::load(tmp.path());
    assert!(result.is_none());
}

#[test]
fn load_returns_none_when_toml_invalid() {
    let tmp = tempfile::tempdir().unwrap();
    let sk = tmp.path().join(".huskies");
    fs::create_dir_all(&sk).unwrap();
    fs::write(sk.join("bot.toml"), "not valid toml {{{").unwrap();
    let result = BotConfig::load(tmp.path());
    assert!(result.is_none());
}

#[test]
fn load_respects_optional_model() {
    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
model = "claude-sonnet-4-6"
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.model.as_deref(), Some("claude-sonnet-4-6"));
}

#[test]
fn load_uses_default_history_size() {
    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
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.history_size, 20);
}

#[test]
fn load_respects_custom_history_size() {
    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
history_size = 50
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.history_size, 50);
}

#[test]
fn load_reads_display_name() {
    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
display_name = "Timmy"
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.display_name.as_deref(), Some("Timmy"));
}

#[test]
fn load_display_name_defaults_to_none_when_absent() {
    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
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert!(config.display_name.is_none());
}

#[test]
fn load_uses_default_permission_timeout() {
    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
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.permission_timeout_secs, 120);
}

#[test]
fn load_respects_custom_permission_timeout() {
    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
permission_timeout_secs = 60
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.permission_timeout_secs, 60);
}

#[test]
fn load_ignores_legacy_require_verified_devices_key() {
    // Old bot.toml files that still have `require_verified_devices = true`
    // must parse successfully — the field is simply ignored now that
    // verification is always enforced unconditionally.
    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
require_verified_devices = true
"#,
    )
    .unwrap();
    // Should still load successfully despite the unknown field.
    let config = BotConfig::load(tmp.path());
    assert!(
        config.is_some(),
        "bot.toml with legacy require_verified_devices key must still load"
    );
}

#[test]
fn load_reads_ambient_rooms() {
    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
ambient_rooms = ["!abc:example.com"]
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.ambient_rooms, vec!["!abc:example.com"]);
}

#[test]
fn load_ambient_rooms_defaults_to_empty_when_absent() {
    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
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert!(config.ambient_rooms.is_empty());
}

#[test]
fn save_ambient_rooms_persists_to_bot_toml() {
    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
"#,
    )
    .unwrap();

    save_ambient_rooms(tmp.path(), &["!abc:example.com".to_string()]);

    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.ambient_rooms, vec!["!abc:example.com"]);
}

#[test]
fn save_ambient_rooms_clears_when_empty() {
    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
ambient_rooms = ["!abc:example.com"]
"#,
    )
    .unwrap();

    save_ambient_rooms(tmp.path(), &[]);

    let config = BotConfig::load(tmp.path()).unwrap();
    assert!(config.ambient_rooms.is_empty());
}

#[test]
fn load_transport_defaults_to_matrix() {
    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
"#,
    )
    .unwrap();
    let config = BotConfig::load(tmp.path()).unwrap();
    assert_eq!(config.transport, "matrix");
}
