"""Unit tests for MCP tool definitions."""

from __future__ import annotations

import pytest

from mcp_standalone.tools import (
    ADVANCED_TOOLS,
    CORE_TOOLS,
    TOOLS,
    VERIFICATION_TOOLS,
    get_all_tools,
    get_tool_by_name,
)


def test_get_all_tools() -> None:
    """Test getting all tools."""
    tools = get_all_tools()
    assert isinstance(tools, list)
    assert len(tools) >= 15  # 2 project + 5 core + 3 verification + 5 advanced tools


def test_core_tools_exist() -> None:
    """Test that all core tools are defined."""
    tool_names = [tool.name for tool in CORE_TOOLS]
    expected_tools = [
        "build_cell",
        "build_cells",
        "list_cells",
        "get_cell_info",
        "download_gds",
    ]
    for expected in expected_tools:
        assert expected in tool_names, f"Tool '{expected}' not found in CORE_TOOLS"


def test_get_tool_by_name() -> None:
    """Test getting a tool by name."""
    # Test existing tool
    tool = get_tool_by_name("build_cell")
    assert tool is not None
    assert tool.name == "build_cell"
    assert tool.description
    assert tool.inputSchema

    # Test non-existing tool
    tool = get_tool_by_name("nonexistent_tool")
    assert tool is None


def test_tool_schemas() -> None:
    """Test that all tools have valid input schemas."""
    for tool in TOOLS:
        assert tool.name
        assert tool.description
        assert tool.inputSchema
        assert "type" in tool.inputSchema
        assert tool.inputSchema["type"] == "object"
        assert "properties" in tool.inputSchema


def test_build_cell_schema() -> None:
    """Test build_cell tool schema."""
    tool = get_tool_by_name("build_cell")
    assert tool is not None

    schema = tool.inputSchema
    assert "name" in schema["properties"]
    assert "name" in schema["required"]
    assert "with_metadata" in schema["properties"]
    assert "register" in schema["properties"]


def test_build_cells_schema() -> None:
    """Test build_cells tool schema."""
    tool = get_tool_by_name("build_cells")
    assert tool is not None

    schema = tool.inputSchema
    assert "names" in schema["properties"]
    assert "names" in schema["required"]
    assert schema["properties"]["names"]["type"] == "array"


def test_list_cells_schema() -> None:
    """Test list_cells tool schema."""
    tool = get_tool_by_name("list_cells")
    assert tool is not None

    schema = tool.inputSchema
    # list_cells has no required parameters
    assert "properties" in schema


def test_get_cell_info_schema() -> None:
    """Test get_cell_info tool schema."""
    tool = get_tool_by_name("get_cell_info")
    assert tool is not None

    schema = tool.inputSchema
    assert "name" in schema["properties"]
    assert "name" in schema["required"]


def test_download_gds_schema() -> None:
    """Test download_gds tool schema."""
    tool = get_tool_by_name("download_gds")
    assert tool is not None

    schema = tool.inputSchema
    assert "path" in schema["properties"]
    assert "path" in schema["required"]


def test_all_tools_unique_names() -> None:
    """Test that all tools have unique names."""
    tool_names = [tool.name for tool in TOOLS]
    assert len(tool_names) == len(set(tool_names)), "Tool names are not unique"


def test_verification_tools_exist() -> None:
    """Test that all verification tools are defined."""
    tool_names = [tool.name for tool in VERIFICATION_TOOLS]
    expected_tools = [
        "check_drc",
        "check_connectivity",
        "check_lvs",
    ]
    for expected in expected_tools:
        assert expected in tool_names, (
            f"Tool '{expected}' not found in VERIFICATION_TOOLS"
        )


def test_check_connectivity_schema() -> None:
    """Test check_connectivity tool schema."""
    tool = get_tool_by_name("check_connectivity")
    assert tool is not None

    schema = tool.inputSchema
    assert "path" in schema["properties"]
    assert "path" in schema["required"]


def test_check_lvs_schema() -> None:
    """Test check_lvs tool schema."""
    tool = get_tool_by_name("check_lvs")
    assert tool is not None

    schema = tool.inputSchema
    assert "cell" in schema["properties"]
    assert "netpath" in schema["properties"]
    assert "cellargs" in schema["properties"]
    assert "cell" in schema["required"]
    assert "netpath" in schema["required"]


def test_check_drc_schema() -> None:
    """Test check_drc tool schema."""
    tool = get_tool_by_name("check_drc")
    assert tool is not None

    schema = tool.inputSchema
    assert "path" in schema["properties"]
    assert "pdk" in schema["properties"]
    assert "process" in schema["properties"]
    assert "timeout" in schema["properties"]
    assert "host" in schema["properties"]
    assert "path" in schema["required"]
    # Optional parameters should not be in required
    assert "pdk" not in schema.get("required", [])
    assert "process" not in schema.get("required", [])


def test_advanced_tools_exist() -> None:
    """Test that all Phase 4 advanced tools are defined."""
    tool_names = [tool.name for tool in ADVANCED_TOOLS]
    expected_tools = [
        "simulate_component",
        "get_port_center",
        "generate_bbox",
        "freeze_cell",
        "get_pdk_info",
    ]
    for expected in expected_tools:
        assert expected in tool_names, f"Tool '{expected}' not found in ADVANCED_TOOLS"


def test_simulate_component_schema() -> None:
    """Test simulate_component tool schema."""
    tool = get_tool_by_name("simulate_component")
    assert tool is not None

    schema = tool.inputSchema
    assert "name" in schema["properties"]
    assert "name" in schema["required"]


def test_get_port_center_schema() -> None:
    """Test get_port_center tool schema."""
    tool = get_tool_by_name("get_port_center")
    assert tool is not None

    schema = tool.inputSchema
    assert "netlist" in schema["properties"]
    assert "instance" in schema["properties"]
    assert "port" in schema["properties"]
    assert "netlist" in schema["required"]
    assert "instance" in schema["required"]
    assert "port" in schema["required"]


def test_generate_bbox_schema() -> None:
    """Test generate_bbox tool schema."""
    tool = get_tool_by_name("generate_bbox")
    assert tool is not None

    schema = tool.inputSchema
    assert "path" in schema["properties"]
    assert "outpath" in schema["properties"]
    assert "layers_to_keep" in schema["properties"]
    assert "bbox_layer" in schema["properties"]
    assert "ignore_ports" in schema["properties"]
    assert "path" in schema["required"]
    # Optional parameters should not be in required
    assert "outpath" not in schema.get("required", [])


def test_freeze_cell_schema() -> None:
    """Test freeze_cell tool schema."""
    tool = get_tool_by_name("freeze_cell")
    assert tool is not None

    schema = tool.inputSchema
    assert "cell_name" in schema["properties"]
    assert "kwargs" in schema["properties"]
    assert "cell_name" in schema["required"]
    # kwargs is optional
    assert "kwargs" not in schema.get("required", [])


def test_get_pdk_info_schema() -> None:
    """Test get_pdk_info tool schema."""
    tool = get_tool_by_name("get_pdk_info")
    assert tool is not None

    schema = tool.inputSchema
    # get_pdk_info has no required parameters beyond optional project
    assert "properties" in schema


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