"""Unit tests for MCP configuration and API key management."""

from __future__ import annotations

import os
from pathlib import Path
from unittest.mock import patch

import pytest

from gfp_mcp.config import (
    MCPConfig,
    _read_api_key_from_toml,
    get_gfp_api_key,
    set_gfp_api_key,
)


class TestMCPConfig:
    """Tests for the MCPConfig class."""

    def test_timeout_default(self) -> None:
        """Test default timeout value."""
        assert MCPConfig.TIMEOUT == 300

    def test_max_retries(self) -> None:
        """Test max retries value."""
        assert MCPConfig.MAX_RETRIES == 3

    def test_retry_backoff(self) -> None:
        """Test retry backoff value."""
        assert MCPConfig.RETRY_BACKOFF == 0.5


class TestReadApiKeyFromToml:
    """Tests for the _read_api_key_from_toml function."""

    def test_file_not_exists(self, tmp_path: Path) -> None:
        """Test reading from a non-existent file."""
        result = _read_api_key_from_toml(tmp_path / "nonexistent.toml")
        assert result is None

    def test_valid_toml_with_key(self, tmp_path: Path) -> None:
        """Test reading a valid TOML file with API key."""
        config_file = tmp_path / "config.toml"
        config_file.write_text("""
[tool.gdsfactoryplus.api]
key = "test-api-key-123"
""")
        result = _read_api_key_from_toml(config_file)
        assert result == "test-api-key-123"

    def test_valid_toml_without_key(self, tmp_path: Path) -> None:
        """Test reading a valid TOML file without API key."""
        config_file = tmp_path / "config.toml"
        config_file.write_text("""
[tool.other]
value = "something"
""")
        result = _read_api_key_from_toml(config_file)
        assert result is None

    def test_invalid_toml(self, tmp_path: Path) -> None:
        """Test reading an invalid TOML file."""
        config_file = tmp_path / "config.toml"
        config_file.write_text("this is not valid toml [[[")
        result = _read_api_key_from_toml(config_file)
        assert result is None

    def test_partial_structure(self, tmp_path: Path) -> None:
        """Test reading a TOML file with partial structure."""
        config_file = tmp_path / "config.toml"
        config_file.write_text("""
[tool.gdsfactoryplus]
other_setting = "value"
""")
        result = _read_api_key_from_toml(config_file)
        assert result is None


class TestGetGfpApiKey:
    """Tests for the get_gfp_api_key function."""

    def test_env_var_gfp_api_key(self) -> None:
        """Test that GFP_API_KEY env var takes highest priority."""
        with patch.dict(os.environ, {"GFP_API_KEY": "env-key-123"}, clear=False):
            result = get_gfp_api_key()
            assert result == "env-key-123"

    def test_global_config_file(self, tmp_path: Path) -> None:
        """Test reading from global config file."""
        # Create a fake home directory with config
        fake_home = tmp_path / "home"
        fake_home.mkdir()
        config_dir = fake_home / ".gdsfactory"
        config_dir.mkdir()
        config_file = config_dir / "gdsfactoryplus.toml"
        config_file.write_text("""
[tool.gdsfactoryplus.api]
key = "global-config-key"
""")

        # Clear env vars and mock home directory
        with (
            patch.dict(os.environ, {}, clear=True),
            patch.object(Path, "home", return_value=fake_home),
            patch.object(Path, "cwd", return_value=tmp_path),
        ):
            result = get_gfp_api_key()
            assert result == "global-config-key"

    def test_local_pyproject_toml(self, tmp_path: Path) -> None:
        """Test reading from local pyproject.toml."""
        # Create a pyproject.toml with API key
        pyproject = tmp_path / "pyproject.toml"
        pyproject.write_text("""
[tool.gdsfactoryplus.api]
key = "local-project-key"
""")

        fake_home = tmp_path / "home"
        fake_home.mkdir()

        # Clear env vars and mock directories
        with (
            patch.dict(os.environ, {}, clear=True),
            patch.object(Path, "home", return_value=fake_home),
            patch.object(Path, "cwd", return_value=tmp_path),
        ):
            result = get_gfp_api_key()
            assert result == "local-project-key"

    def test_no_api_key_found(self, tmp_path: Path) -> None:
        """Test when no API key is found anywhere."""
        fake_home = tmp_path / "home"
        fake_home.mkdir()

        with (
            patch.dict(os.environ, {}, clear=True),
            patch.object(Path, "home", return_value=fake_home),
            patch.object(Path, "cwd", return_value=tmp_path),
        ):
            result = get_gfp_api_key()
            assert result is None


class TestSetGfpApiKey:
    """Tests for the set_gfp_api_key function."""

    def test_set_api_key_creates_file(self, tmp_path: Path) -> None:
        """Test that setting API key creates the config file."""
        fake_home = tmp_path / "home"
        fake_home.mkdir()

        with patch.object(Path, "home", return_value=fake_home):
            set_gfp_api_key("new-api-key-789")

        config_file = fake_home / ".gdsfactory" / "gdsfactoryplus.toml"
        assert config_file.exists()

        content = config_file.read_text()
        assert "new-api-key-789" in content

    def test_set_api_key_updates_existing(self, tmp_path: Path) -> None:
        """Test that setting API key updates existing config."""
        fake_home = tmp_path / "home"
        config_dir = fake_home / ".gdsfactory"
        config_dir.mkdir(parents=True)

        config_file = config_dir / "gdsfactoryplus.toml"
        config_file.write_text("""
[tool.gdsfactoryplus.api]
key = "old-key"
host = "https://api.example.com"
""")

        with patch.object(Path, "home", return_value=fake_home):
            set_gfp_api_key("updated-key")

        content = config_file.read_text()
        assert "updated-key" in content

    def test_set_empty_api_key_raises(self) -> None:
        """Test that setting empty API key raises ValueError."""
        with pytest.raises(ValueError, match="API key is required"):
            set_gfp_api_key("")

    def test_set_none_api_key_raises(self) -> None:
        """Test that setting None API key raises ValueError."""
        with pytest.raises(ValueError, match="API key is required"):
            set_gfp_api_key(None)  # type: ignore[arg-type]

    def test_creates_directory_if_not_exists(self, tmp_path: Path) -> None:
        """Test that setting API key creates the .gdsfactory directory."""
        fake_home = tmp_path / "home"
        fake_home.mkdir()
        # Don't create the .gdsfactory directory

        with patch.object(Path, "home", return_value=fake_home):
            set_gfp_api_key("test-key")

        config_dir = fake_home / ".gdsfactory"
        assert config_dir.exists()
        assert config_dir.is_dir()


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
