"""Tests for config CLI helpers."""

import json
from pathlib import Path

import pytest

from maniple_mcp import config as config_module
from maniple_mcp.config import ConfigError, load_config
from maniple_mcp.config_cli import (
    get_config_value,
    init_config,
    load_effective_config_data,
    render_config_json,
    set_config_value,
)


@pytest.fixture(autouse=True)
def config_path(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
    """Point config path to a temp location for deterministic tests."""
    path = tmp_path / "config.json"
    monkeypatch.setattr(config_module, "CONFIG_PATH", path)
    return path


class TestConfigInit:
    """Tests for config init helper."""

    def test_init_creates_default(self, config_path: Path):
        """init_config writes the default config file."""
        result = init_config()
        assert result == config_path
        assert config_path.exists()

    def test_init_errors_when_exists(self, config_path: Path):
        """init_config errors without --force if file exists."""
        config_path.write_text("{}")
        with pytest.raises(ConfigError, match="already exists"):
            init_config()


class TestConfigShow:
    """Tests for config show helper."""

    def test_show_merges_env_overrides(self, config_path: Path):
        """render_config_json applies env overrides on top of config."""
        config_path.write_text(json.dumps({
            "version": 1,
            "commands": {"claude": "/from/config"},
            "events": {"max_size_mb": 2},
        }))
        env = {
            "MANIPLE_COMMAND": "from-env",
            "MANIPLE_EVENTS_MAX_SIZE_MB": "5",
        }
        data = load_effective_config_data(env=env)
        assert data["commands"]["claude"] == "from-env"
        assert data["events"]["max_size_mb"] == 5

    def test_show_renders_json(self, config_path: Path):
        """render_config_json returns formatted JSON."""
        config_path.write_text(json.dumps({"version": 1}))
        payload = render_config_json()
        parsed = json.loads(payload)
        assert parsed["version"] == 1


class TestConfigGet:
    """Tests for config get helper."""

    def test_get_reads_dotted_value(self, config_path: Path):
        """get_config_value returns values by dotted path."""
        config_path.write_text(json.dumps({
            "version": 1,
            "defaults": {"layout": "new"},
        }))
        assert get_config_value("defaults.layout") == "new"

    def test_get_reads_env_override(self, config_path: Path):
        """get_config_value returns env-overridden values."""
        config_path.write_text(json.dumps({"version": 1}))
        env = {"MANIPLE_TERMINAL_BACKEND": "tmux"}
        assert get_config_value("terminal.backend", env=env) == "tmux"


class TestConfigSet:
    """Tests for config set helper."""

    def test_set_creates_file_and_saves(self, config_path: Path):
        """set_config_value creates file and persists updates."""
        set_config_value("defaults.skip_permissions", "true")
        config = load_config()
        assert config.defaults.skip_permissions is True

    def test_set_validates_values(self, config_path: Path):
        """set_config_value validates against the schema."""
        with pytest.raises(ConfigError, match="defaults.layout must be one of"):
            set_config_value("defaults.layout", "grid")

    def test_set_rejects_unknown_key(self, config_path: Path):
        """set_config_value rejects unknown keys."""
        with pytest.raises(ConfigError, match="Unknown config key"):
            set_config_value("defaults.unknown", "true")

    def test_set_stale_threshold_minutes(self, config_path: Path):
        """set_config_value persists stale_threshold_minutes."""
        set_config_value("events.stale_threshold_minutes", "30")
        config = load_config()
        assert config.events.stale_threshold_minutes == 30


class TestStaleThresholdEnvOverride:
    """Tests for stale_threshold_minutes env override."""

    def test_env_overrides_config(self, config_path: Path):
        """MANIPLE_STALE_THRESHOLD_MINUTES overrides file config."""
        config_path.write_text(json.dumps({
            "version": 1,
            "events": {"stale_threshold_minutes": 15},
        }))
        env = {"MANIPLE_STALE_THRESHOLD_MINUTES": "25"}
        data = load_effective_config_data(env=env)
        assert data["events"]["stale_threshold_minutes"] == 25

    def test_env_overrides_default(self, config_path: Path):
        """MANIPLE_STALE_THRESHOLD_MINUTES overrides default when no file."""
        env = {"MANIPLE_STALE_THRESHOLD_MINUTES": "5"}
        data = load_effective_config_data(env=env)
        assert data["events"]["stale_threshold_minutes"] == 5

    def test_invalid_env_value_ignored(self, config_path: Path):
        """Non-integer env value is silently ignored."""
        config_path.write_text(json.dumps({
            "version": 1,
            "events": {"stale_threshold_minutes": 15},
        }))
        env = {"MANIPLE_STALE_THRESHOLD_MINUTES": "not_a_number"}
        data = load_effective_config_data(env=env)
        assert data["events"]["stale_threshold_minutes"] == 15

    def test_deprecated_env_fallback(self, config_path: Path):
        """Deprecated CLAUDE_TEAM_STALE_THRESHOLD_MINUTES is still honored."""
        env = {"CLAUDE_TEAM_STALE_THRESHOLD_MINUTES": "7"}
        data = load_effective_config_data(env=env)
        assert data["events"]["stale_threshold_minutes"] == 7

    def test_env_precedence(self, config_path: Path):
        """MANIPLE_STALE_THRESHOLD_MINUTES takes precedence over deprecated env var."""
        env = {"MANIPLE_STALE_THRESHOLD_MINUTES": "9", "CLAUDE_TEAM_STALE_THRESHOLD_MINUTES": "7"}
        data = load_effective_config_data(env=env)
        assert data["events"]["stale_threshold_minutes"] == 9
