"""Tests for gfp_mcp.tools package initialization.

These tests verify the tool handler registry and lookup functions.
"""

from __future__ import annotations

import pytest

from gfp_mcp.tools import (
    PROJECT_PARAM_SCHEMA,
    TOOL_HANDLERS,
    EndpointMapping,
    ToolHandler,
    add_project_param,
    get_all_tools,
    get_handler,
    get_tool_by_name,
)


class TestProjectParamSchema:
    """Tests for PROJECT_PARAM_SCHEMA constant."""

    def test_schema_structure(self) -> None:
        """Test PROJECT_PARAM_SCHEMA has correct structure."""
        assert "project" in PROJECT_PARAM_SCHEMA
        project_schema = PROJECT_PARAM_SCHEMA["project"]

        assert project_schema["type"] == "string"
        assert "description" in project_schema
        assert len(project_schema["description"]) > 0


class TestAddProjectParam:
    """Tests for add_project_param function."""

    def test_adds_to_empty_properties(self) -> None:
        """Test adding project param to schema with no properties."""
        schema: dict = {"type": "object"}
        result = add_project_param(schema)

        assert "properties" in result
        assert "project" in result["properties"]
        assert result["properties"]["project"]["type"] == "string"

    def test_adds_to_existing_properties(self) -> None:
        """Test adding project param preserves existing properties."""
        schema = {
            "type": "object",
            "properties": {
                "name": {"type": "string"},
                "count": {"type": "integer"},
            },
        }
        result = add_project_param(schema)

        # Original properties preserved
        assert "name" in result["properties"]
        assert "count" in result["properties"]
        # Project added
        assert "project" in result["properties"]

    def test_returns_same_dict(self) -> None:
        """Test that function modifies and returns the same dict."""
        schema = {"type": "object", "properties": {}}
        result = add_project_param(schema)

        assert result is schema


class TestToolHandlersRegistry:
    """Tests for TOOL_HANDLERS registry."""

    def test_registry_is_dict(self) -> None:
        """Test that TOOL_HANDLERS is a dictionary."""
        assert isinstance(TOOL_HANDLERS, dict)

    def test_registry_has_all_handlers(self) -> None:
        """Test that registry contains all expected handlers."""
        expected_tools = {
            "list_projects",
            "get_project_info",
            "build_cells",
            "list_cells",
            "get_cell_info",
            "check_drc",
            "check_connectivity",
            "check_lvs",
            "simulate_component",
            "list_samples",
            "get_sample_file",
        }
        assert set(TOOL_HANDLERS.keys()) == expected_tools
        assert len(TOOL_HANDLERS) == 11


class TestGetAllTools:
    """Tests for get_all_tools function."""

    def test_returns_list(self) -> None:
        """Test that get_all_tools returns a list."""
        result = get_all_tools()
        assert isinstance(result, list)

    def test_returns_all_tools(self) -> None:
        """Test returns all registered tools."""
        result = get_all_tools()
        assert len(result) == 11
        # Verify they are Tool objects
        for tool in result:
            assert hasattr(tool, "name")
            assert hasattr(tool, "description")
            assert hasattr(tool, "inputSchema")


class TestGetToolByName:
    """Tests for get_tool_by_name function."""

    def test_unknown_tool_returns_none(self) -> None:
        """Test that unknown tool returns None."""
        result = get_tool_by_name("nonexistent_tool")
        assert result is None

    def test_empty_string_returns_none(self) -> None:
        """Test that empty string returns None."""
        result = get_tool_by_name("")
        assert result is None


class TestGetHandler:
    """Tests for get_handler function."""

    def test_unknown_handler_returns_none(self) -> None:
        """Test that unknown handler returns None."""
        result = get_handler("nonexistent_handler")
        assert result is None

    def test_empty_string_returns_none(self) -> None:
        """Test that empty string returns None."""
        result = get_handler("")
        assert result is None


class TestExports:
    """Tests for module exports."""

    def test_endpoint_mapping_exported(self) -> None:
        """Test EndpointMapping is properly exported."""
        assert EndpointMapping is not None

        # Can create instance
        mapping = EndpointMapping(method="GET", path="/test")
        assert mapping.method == "GET"

    def test_tool_handler_exported(self) -> None:
        """Test ToolHandler is properly exported."""
        assert ToolHandler is not None

        # Cannot instantiate abstract class
        with pytest.raises(TypeError):
            ToolHandler()  # type: ignore[abstract]


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