"""Tests for ievo config command."""

from __future__ import annotations

from pathlib import Path
from unittest.mock import patch

import pytest
import typer

from ievo.commands.config_cmd import config_delete, config_get, config_list, config_set
from ievo.core.credentials import ensure_keys, get_credential
from ievo.core.global_config import get_config, load_global_config


@pytest.fixture(autouse=True)
def _mock_home(tmp_path: Path):
    """Mock ensure_home to use tmp_path for all config_cmd tests."""
    fake_home = tmp_path / ".fake-ievo"
    fake_home.mkdir()
    ensure_keys(fake_home)
    load_global_config(fake_home)
    with patch("ievo.commands.config_cmd.ensure_home", return_value=fake_home):
        yield fake_home


def test_config_set_sensitive_key(_mock_home: Path) -> None:
    """Sensitive keys are encrypted in credentials store."""
    config_set(key="ANTHROPIC_API_KEY", value="sk-ant-test123")
    assert get_credential(_mock_home, "ANTHROPIC_API_KEY") == "sk-ant-test123"


def test_config_set_plain_key(_mock_home: Path) -> None:
    """Plain keys are stored in config.json."""
    config_set(key="default_model", value="opus")
    assert get_config(_mock_home, "default_model") == "opus"


def test_config_get_sensitive(_mock_home: Path, capsys) -> None:
    """Getting a sensitive key masks the value."""
    from ievo.core.credentials import set_credential

    set_credential(_mock_home, "GITHUB_TOKEN", "ghp_1234567890")
    config_get(key="GITHUB_TOKEN")
    # No assertion on output (Rich renders to console, not captured by capsys)
    # Just verify it doesn't crash


def test_config_get_not_found(_mock_home: Path) -> None:
    """Getting a missing key raises Exit."""
    with pytest.raises(typer.Exit):
        config_get(key="NONEXISTENT_TOKEN")


def test_config_list(_mock_home: Path) -> None:
    """List shows both config and credentials."""
    from ievo.core.credentials import set_credential

    set_credential(_mock_home, "ANTHROPIC_API_KEY", "sk-test")
    # Should not crash
    config_list()


def test_config_delete_sensitive(_mock_home: Path) -> None:
    """Deleting a sensitive key removes from credentials."""
    from ievo.core.credentials import set_credential

    set_credential(_mock_home, "GITHUB_TOKEN", "ghp_test")
    config_delete(key="GITHUB_TOKEN")
    assert get_credential(_mock_home, "GITHUB_TOKEN") is None


def test_config_delete_plain(_mock_home: Path) -> None:
    """Deleting a plain key removes from config.json."""
    from ievo.core.global_config import set_config

    set_config(_mock_home, "my_setting", "my_value")
    assert get_config(_mock_home, "my_setting") == "my_value"
    config_delete(key="my_setting")
    assert get_config(_mock_home, "my_setting") is None


def test_config_get_plain_not_found(_mock_home: Path) -> None:
    """Getting a missing non-sensitive key raises Exit."""
    with pytest.raises(typer.Exit):
        config_get(key="nonexistent_setting")


def test_config_get_plain_found(_mock_home: Path) -> None:
    """Getting an existing plain key shows value."""
    from ievo.core.global_config import set_config

    set_config(_mock_home, "default_model", "opus")
    config_get(key="default_model")  # should not raise


def test_config_list_empty(_mock_home: Path) -> None:
    """List with no config or credentials shows warning."""
    import json

    # Force empty config.json to hit both-empty branch (line 79)
    (_mock_home / "config.json").write_text(json.dumps({}))
    load_global_config(_mock_home)  # reload with empty
    with patch("ievo.commands.config_cmd.load_global_config", return_value={}):
        config_list()  # should not raise, shows "No configuration found"


def test_config_list_with_config_no_creds(_mock_home: Path) -> None:
    """List with config but no credentials."""
    from ievo.core.global_config import set_config

    set_config(_mock_home, "default_model", "opus")
    config_list()  # should not raise


def test_config_delete_sensitive_not_found(_mock_home: Path) -> None:
    """Deleting a missing sensitive key raises Exit."""
    with pytest.raises(typer.Exit):
        config_delete(key="GITHUB_TOKEN")


def test_config_delete_plain_not_found(_mock_home: Path) -> None:
    """Deleting a missing plain key raises Exit."""
    with pytest.raises(typer.Exit):
        config_delete(key="nonexistent_setting")
