"""Unit tests for constants helpers (defensive config / auth headers)."""
import constants


def test_service_headers_empty_when_no_key(monkeypatch):
    monkeypatch.setattr(constants, "API_SHARED_KEY", "")
    assert constants.service_headers() == {}


def test_service_headers_with_key(monkeypatch):
    monkeypatch.setattr(constants, "API_SHARED_KEY", "s3cr3t")
    assert constants.service_headers() == {"X-Conjurer-Api-Key": "s3cr3t"}


def test_load_json_missing_returns_fallback(tmp_path):
    missing = tmp_path / "nope.json"
    assert constants._load_json(str(missing), {"fallback": 1}) == {"fallback": 1}


def test_load_json_valid(tmp_path):
    good = tmp_path / "ok.json"
    good.write_text('{"a": 2}', encoding="utf-8")
    assert constants._load_json(str(good), {}) == {"a": 2}


def test_load_json_corrupt_returns_fallback(tmp_path):
    bad = tmp_path / "bad.json"
    bad.write_text("{ not valid json", encoding="utf-8")
    assert constants._load_json(str(bad), []) == []


def test_conan_defaults_present():
    # Feature toggles default to "off" so the bridge stays dormant.
    assert constants.CONAN_JOIN_CHANNEL_ID == 0
    assert constants.CONAN_RCON_HOST == ""


def test_ai_configs_expose_gpt_and_claude_backends():
    cfgs = constants.AI_CONFIGS
    assert cfgs["gpt"]["provider"] == "openai"
    assert cfgs["claude"]["provider"] == "anthropic"
    # Claude carries a max_tokens (Anthropic requires it) and omits temperature
    # (Opus 4.8 / Sonnet 5 reject sampling params).
    assert "max_tokens" in cfgs["claude"]
    assert "temperature" not in cfgs["claude"]


def test_default_ai_config_is_a_known_config():
    # The single startup switch must always resolve to a real, selectable config.
    assert constants.DEFAULT_AI_CONFIG in constants.AI_CONFIGS
