"""Tests for server registry integration with gdsfactoryplus."""

from __future__ import annotations

import json
import tempfile
from pathlib import Path

from mcp_standalone.registry import ServerInfo, ServerRegistry, get_registry_path


def test_get_registry_path():
    """Test that registry path points to correct location."""
    path = get_registry_path()
    assert path == Path.home() / ".gdsfactory" / "server-registry.json"
    assert path.parent.exists()  # Directory should be created


def test_server_info_creation():
    """Test ServerInfo initialization and properties."""
    info = ServerInfo(
        port=8787,
        pid=12345,
        project_path="/path/to/project",
        project_name="test_project",
        pdk="test_pdk",
        started_at="2024-01-01T00:00:00Z",
        last_heartbeat="2024-01-01T00:01:00Z",
    )

    assert info.port == 8787
    assert info.pid == 12345
    assert info.project_path == "/path/to/project"
    assert info.project_name == "test_project"
    assert info.pdk == "test_pdk"
    assert info.started_at == "2024-01-01T00:00:00Z"
    assert info.last_heartbeat == "2024-01-01T00:01:00Z"


def test_server_info_to_dict():
    """Test ServerInfo serialization to dict."""
    info = ServerInfo(
        port=8787,
        pid=12345,
        project_path="/path/to/project",
        project_name="test_project",
        pdk="test_pdk",
        started_at="2024-01-01T00:00:00Z",
    )

    data = info.to_dict()
    assert data["port"] == 8787
    assert data["pid"] == 12345
    assert data["project_path"] == "/path/to/project"
    assert data["project_name"] == "test_project"
    assert data["pdk"] == "test_pdk"
    assert data["started_at"] == "2024-01-01T00:00:00Z"


def test_server_info_from_dict():
    """Test ServerInfo deserialization from dict."""
    data = {
        "port": 8787,
        "pid": 12345,
        "project_path": "/path/to/project",
        "project_name": "test_project",
        "pdk": "test_pdk",
        "started_at": "2024-01-01T00:00:00Z",
        "last_heartbeat": "2024-01-01T00:01:00Z",
    }

    info = ServerInfo.from_dict(data)
    assert info.port == 8787
    assert info.pid == 12345
    assert info.project_path == "/path/to/project"
    assert info.project_name == "test_project"
    assert info.pdk == "test_pdk"
    assert info.started_at == "2024-01-01T00:00:00Z"
    assert info.last_heartbeat == "2024-01-01T00:01:00Z"


def test_registry_empty():
    """Test registry with no registered servers."""
    with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
        temp_path = Path(f.name)
        json.dump({"servers": {}}, f)

    try:
        registry = ServerRegistry(registry_path=temp_path)
        servers = registry.list_servers()
        assert servers == []
        assert registry.get_server(8787) is None
        assert registry.get_server_by_project("test") is None
    finally:
        temp_path.unlink()


def test_registry_read_servers():
    """Test reading servers from registry file."""
    with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
        temp_path = Path(f.name)
        data = {
            "servers": {
                "8787": {
                    "port": 8787,
                    "pid": 12345,
                    "project_path": "/path/to/project1",
                    "project_name": "project1",
                    "pdk": "test_pdk",
                    "started_at": "2024-01-01T00:00:00Z",
                    "last_heartbeat": "2024-01-01T00:01:00Z",
                },
                "8788": {
                    "port": 8788,
                    "pid": 12346,
                    "project_path": "/path/to/project2",
                    "project_name": "project2",
                    "pdk": None,
                    "started_at": "2024-01-01T00:00:00Z",
                    "last_heartbeat": "2024-01-01T00:01:00Z",
                },
            }
        }
        json.dump(data, f)

    try:
        registry = ServerRegistry(registry_path=temp_path)

        # Test list_servers
        servers = registry.list_servers(include_dead=True)
        assert len(servers) == 2
        assert servers[0].project_name in ["project1", "project2"]

        # Test get_server
        server = registry.get_server(8787)
        # May be None if process is not running
        if server is not None:
            assert server.port == 8787
            assert server.project_name == "project1"

        # Test get_server_by_project
        server = registry.get_server_by_project("project2")
        # May be None if process is not running
        if server is not None:
            assert server.port == 8788
            assert server.project_path == "/path/to/project2"

        # Test get_server_by_project with path
        server = registry.get_server_by_project("/path/to/project1")
        if server is not None:
            assert server.project_name == "project1"

    finally:
        temp_path.unlink()


def test_registry_nonexistent_file():
    """Test registry handles nonexistent file gracefully."""
    temp_path = Path("/tmp/nonexistent_registry_test.json")
    if temp_path.exists():
        temp_path.unlink()

    registry = ServerRegistry(registry_path=temp_path)
    servers = registry.list_servers()
    assert servers == []


def test_registry_corrupted_file():
    """Test registry handles corrupted JSON gracefully."""
    with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
        temp_path = Path(f.name)
        f.write("{ invalid json }")

    try:
        registry = ServerRegistry(registry_path=temp_path)
        servers = registry.list_servers()
        assert servers == []
    finally:
        temp_path.unlink()


def test_server_info_is_alive():
    """Test process liveness check."""
    import os

    # Test with current process (should be alive)
    info = ServerInfo(
        port=8787,
        pid=os.getpid(),
        project_path="/path/to/project",
        project_name="test_project",
    )

    # If psutil is available, should return True
    # If not available, should also return True (optimistic)
    assert info.is_alive() is True

    # Test with obviously invalid PID
    info_dead = ServerInfo(
        port=8787,
        pid=999999,
        project_path="/path/to/project",
        project_name="test_project",
    )

    # If psutil is available, should return False
    # If not available, should return True (optimistic)
    result = info_dead.is_alive()
    assert isinstance(result, bool)
