"""Tests for Config singleton."""

import os

import pytest

from ai_qa.core.config import configure, get_config, reset_config


@pytest.fixture(autouse=True)
def reset_config_after_test():
    """Reset config after each test."""
    yield
    reset_config()


def test_default_config() -> None:
    """Test sensible defaults."""
    reset_config()
    config = get_config()
    assert config.provider is None or isinstance(config.provider, str)
    assert config.model is None
    assert config.api_key is None
    assert config.default_threshold == 0.5
    assert config.max_retries == 3
    assert config.timeout_seconds == 30.0
    assert config.cache_enabled is True
    assert config.cache_dir == ".ai_qa_cache"
    assert config.parallelism == 4
    assert config.verbose is False


def test_configure_sets_values() -> None:
    """Test that configure() updates config."""
    reset_config()
    config = configure(
        provider="anthropic",
        model="claude-3",
        default_threshold=0.7,
        parallelism=8,
    )
    assert config.provider == "anthropic"
    assert config.model == "claude-3"
    assert config.default_threshold == 0.7
    assert config.parallelism == 8


def test_configure_validates_threshold() -> None:
    """Test that bad threshold raises error."""
    reset_config()
    with pytest.raises(Exception):
        configure(default_threshold=1.5)

    with pytest.raises(Exception):
        configure(default_threshold=-0.1)


def test_configure_validates_max_retries() -> None:
    """Test that negative max_retries raises error."""
    reset_config()
    with pytest.raises(Exception):
        configure(max_retries=-1)


def test_configure_validates_timeout() -> None:
    """Test that non-positive timeout raises error."""
    reset_config()
    with pytest.raises(Exception):
        configure(timeout_seconds=0)

    with pytest.raises(Exception):
        configure(timeout_seconds=-1)


def test_configure_validates_parallelism() -> None:
    """Test that non-positive parallelism raises error."""
    reset_config()
    with pytest.raises(Exception):
        configure(parallelism=0)

    with pytest.raises(Exception):
        configure(parallelism=-1)


def test_auto_detect_anthropic() -> None:
    """Test ANTHROPIC_API_KEY env var detected."""
    reset_config()
    # Save original env
    original = os.environ.get("ANTHROPIC_API_KEY")
    try:
        os.environ["ANTHROPIC_API_KEY"] = "test-key"
        # Clear other env vars
        openai_original = os.environ.get("OPENAI_API_KEY")
        if "OPENAI_API_KEY" in os.environ:
            del os.environ["OPENAI_API_KEY"]

        reset_config()
        config = get_config()
        assert config.provider == "anthropic"

        if openai_original:
            os.environ["OPENAI_API_KEY"] = openai_original
    finally:
        if original:
            os.environ["ANTHROPIC_API_KEY"] = original
        elif "ANTHROPIC_API_KEY" in os.environ:
            del os.environ["ANTHROPIC_API_KEY"]


def test_auto_detect_openai() -> None:
    """Test OPENAI_API_KEY env var detected."""
    reset_config()
    original = os.environ.get("OPENAI_API_KEY")
    anthropic_original = os.environ.get("ANTHROPIC_API_KEY")
    try:
        # Clear anthropic key
        if "ANTHROPIC_API_KEY" in os.environ:
            del os.environ["ANTHROPIC_API_KEY"]
        os.environ["OPENAI_API_KEY"] = "test-key"

        reset_config()
        config = get_config()
        assert config.provider == "openai"

        if anthropic_original:
            os.environ["ANTHROPIC_API_KEY"] = anthropic_original
    finally:
        if original:
            os.environ["OPENAI_API_KEY"] = original
        elif "OPENAI_API_KEY" in os.environ:
            del os.environ["OPENAI_API_KEY"]


def test_auto_detect_none() -> None:
    """Test no env var, provider is None."""
    reset_config()
    # Save originals
    anthropic_original = os.environ.pop("ANTHROPIC_API_KEY", None)
    openai_original = os.environ.pop("OPENAI_API_KEY", None)
    try:
        reset_config()
        config = get_config()
        assert config.provider is None
    finally:
        if anthropic_original:
            os.environ["ANTHROPIC_API_KEY"] = anthropic_original
        if openai_original:
            os.environ["OPENAI_API_KEY"] = openai_original


def test_configure_multiple_times() -> None:
    """Test that last call wins."""
    reset_config()
    config1 = configure(provider="anthropic")
    assert config1.provider == "anthropic"

    config2 = configure(provider="openai")
    assert config2.provider == "openai"

    # Verify it's the same instance
    assert get_config().provider == "openai"


def test_get_config_returns_singleton() -> None:
    """Test that same instance is returned."""
    reset_config()
    config1 = get_config()
    config2 = get_config()
    assert config1 is config2


def test_config_with_explicit_api_key() -> None:
    """Test that explicit API key is stored."""
    reset_config()
    config = configure(api_key="my-secret-key")
    assert config.api_key == "my-secret-key"


def test_config_with_base_url() -> None:
    """Test that base_url is stored."""
    reset_config()
    config = configure(base_url="http://localhost:11434")
    assert config.base_url == "http://localhost:11434"
