"""Tests for bandito configuration."""

from __future__ import annotations

from pathlib import Path

from bandito.config import (
    _DEFAULT_TRACES_DIR,
    AgentSettings,
    BanditoConfig,
    ProjectSettings,
    load_config,
    resolve_traces_dir,
    save_config,
)


class TestLoadSaveConfig:
    def test_missing_file_returns_defaults(self, tmp_path):
        config = load_config(tmp_path / "nonexistent.toml")
        assert config.traces_dir == _DEFAULT_TRACES_DIR
        assert config.projects == {}

    def test_round_trip(self, tmp_path):
        path = tmp_path / "config.toml"
        config = BanditoConfig(
            traces_dir="/data/traces",
            projects={
                "my-bot": ProjectSettings(traces_dir="/data/my-bot"),
            },
        )
        save_config(config, path)
        loaded = load_config(path)

        assert loaded.traces_dir == "/data/traces"
        assert "my-bot" in loaded.projects
        assert loaded.projects["my-bot"].traces_dir == "/data/my-bot"

    def test_agent_settings_default_enabled(self):
        config = BanditoConfig()
        assert config.agent.enabled is True
        assert config.agent.mcp_enabled is False

    def test_agent_mcp_enabled_round_trip(self, tmp_path):
        path = tmp_path / "config.toml"
        config = BanditoConfig(agent=AgentSettings(enabled=True, mcp_enabled=True))
        save_config(config, path)
        loaded = load_config(path)
        assert loaded.agent.enabled is True
        assert loaded.agent.mcp_enabled is True

    def test_agent_disabled_round_trip(self, tmp_path):
        path = tmp_path / "config.toml"
        config = BanditoConfig(agent=AgentSettings(enabled=False, mcp_enabled=False))
        save_config(config, path)
        loaded = load_config(path)
        assert loaded.agent.enabled is False
        assert loaded.agent.mcp_enabled is False

    def test_minimal_config(self, tmp_path):
        path = tmp_path / "config.toml"
        config = BanditoConfig(traces_dir="/tmp/traces")
        save_config(config, path)
        loaded = load_config(path)
        assert loaded.traces_dir == "/tmp/traces"
        assert loaded.projects == {}

    def test_creates_parent_dirs(self, tmp_path):
        path = tmp_path / "deep" / "nested" / "config.toml"
        save_config(BanditoConfig(), path)
        assert path.exists()

    def test_toml_output_format(self, tmp_path):
        path = tmp_path / "config.toml"
        config = BanditoConfig(traces_dir="./traces")
        save_config(config, path)
        text = path.read_text()
        assert 'traces_dir = "./traces"' in text


class TestResolveTracesDir:
    def test_default(self):
        config = BanditoConfig()
        assert resolve_traces_dir(config) == _DEFAULT_TRACES_DIR

    def test_global_override(self):
        config = BanditoConfig(traces_dir="/data/traces")
        assert resolve_traces_dir(config) == "/data/traces"

    def test_project_override(self):
        config = BanditoConfig(
            traces_dir="/data/traces",
            projects={"bot": ProjectSettings(traces_dir="/data/bot")},
        )
        assert resolve_traces_dir(config, "bot") == "/data/bot"

    def test_project_fallback_to_global(self):
        config = BanditoConfig(
            traces_dir="/data/traces",
            projects={"bot": ProjectSettings()},
        )
        assert resolve_traces_dir(config, "bot") == "/data/traces"

    def test_unknown_project_uses_global(self):
        config = BanditoConfig(traces_dir="/data/traces")
        assert resolve_traces_dir(config, "unknown") == "/data/traces"

    def test_env_var_wins(self, monkeypatch):
        monkeypatch.setenv("BANDITO_TRACES_DIR", "/env/traces")
        config = BanditoConfig(traces_dir="/config/traces")
        assert resolve_traces_dir(config) == "/env/traces"


class TestInteractiveConfig:
    def test_interactive_creates_file(self, tmp_path, monkeypatch):
        path = tmp_path / "config.toml"
        inputs = iter([
            "",             # storage backend (accept default)
            "/my/traces",   # traces dir
            "",             # add project (skip)
        ])
        monkeypatch.setattr("builtins.input", lambda _: next(inputs))

        from bandito.config import run_config_interactive

        run_config_interactive(path)
        assert path.exists()

        config = load_config(path)
        assert config.traces_dir == "/my/traces"

    def test_interactive_with_project(self, tmp_path, monkeypatch):
        path = tmp_path / "config.toml"
        inputs = iter([
            "",             # storage backend (accept default)
            "./traces",     # traces dir
            "my-bot",       # add project
            "/bot/traces",  # project traces dir
            "",             # another project (skip)
        ])
        monkeypatch.setattr("builtins.input", lambda _: next(inputs))

        from bandito.config import run_config_interactive

        run_config_interactive(path)

        config = load_config(path)
        assert config.traces_dir == "./traces"
        assert "my-bot" in config.projects
        assert config.projects["my-bot"].traces_dir == "/bot/traces"


class TestSDKConfigIntegration:
    def test_sdk_uses_config_traces_dir(self, tmp_path, monkeypatch):
        """SDK default store should pick up traces_dir from config."""
        config_path = tmp_path / ".bandito" / "config.toml"
        traces_dir = str(tmp_path / "custom_traces")

        from bandito.config import save_config

        save_config(BanditoConfig(traces_dir=traces_dir), config_path)

        # Point the SDK at this config
        monkeypatch.setattr("bandito.config._CONFIG_PATH", config_path)

        # Reset cached store so resolution runs again
        import bandito

        monkeypatch.setattr(bandito, "_store_cache", {})

        store = bandito._get_store()
        assert store._directory == traces_dir

    def test_sdk_env_var_overrides_config(self, tmp_path, monkeypatch):
        config_path = tmp_path / ".bandito" / "config.toml"
        from bandito.config import save_config

        save_config(BanditoConfig(traces_dir="/config/traces"), config_path)
        monkeypatch.setattr("bandito.config._CONFIG_PATH", config_path)
        monkeypatch.setenv("BANDITO_TRACES_DIR", "/env/traces")

        import bandito

        monkeypatch.setattr(bandito, "_store_cache", {})

        store = bandito._get_store()
        assert store._directory == "/env/traces"

    def test_sdk_falls_back_to_default(self, tmp_path, monkeypatch):
        # No config file, no env var
        monkeypatch.setattr("bandito.config._CONFIG_PATH", tmp_path / "nope.toml")
        monkeypatch.delenv("BANDITO_TRACES_DIR", raising=False)

        import bandito

        monkeypatch.setattr(bandito, "_store_cache", {})

        store = bandito._get_store()
        assert store._directory == _DEFAULT_TRACES_DIR
