"""Unit tests for the stdio transport module."""

import pytest
from mcp.server.fastmcp import FastMCP

from nextcloud_mcp_server.config import _reload_config
from nextcloud_mcp_server.config_validators import AuthMode
from nextcloud_mcp_server.stdio import get_stdio_mcp


@pytest.fixture
def single_user_env(monkeypatch):
    """Set up environment variables for single-user BasicAuth mode."""
    monkeypatch.setenv("NEXTCLOUD_HOST", "https://cloud.example.com")
    monkeypatch.setenv("NEXTCLOUD_USERNAME", "admin")
    monkeypatch.setenv("NEXTCLOUD_PASSWORD", "secret")
    # Ensure no explicit deployment mode leaks from other tests
    monkeypatch.delenv("MCP_DEPLOYMENT_MODE", raising=False)
    _reload_config()
    yield
    _reload_config()


@pytest.mark.unit
def test_get_stdio_mcp_returns_fastmcp(single_user_env):
    """get_stdio_mcp returns a FastMCP instance with correct env vars."""
    mcp = get_stdio_mcp()
    assert isinstance(mcp, FastMCP)


@pytest.mark.unit
def test_get_stdio_mcp_rejects_config_errors(monkeypatch):
    """get_stdio_mcp raises ValueError when validate_configuration reports errors."""
    monkeypatch.setattr(
        "nextcloud_mcp_server.stdio.validate_configuration",
        lambda _settings: (AuthMode.SINGLE_USER_BASIC, ["missing nextcloud_host"]),
    )
    with pytest.raises(ValueError, match="Configuration validation failed"):
        get_stdio_mcp()


@pytest.mark.unit
def test_get_stdio_mcp_rejects_non_single_user_mode(monkeypatch):
    """get_stdio_mcp raises ValueError for non-single-user modes."""
    monkeypatch.setattr(
        "nextcloud_mcp_server.stdio.validate_configuration",
        lambda _settings: (AuthMode.MULTI_USER_BASIC, []),
    )
    with pytest.raises(ValueError, match="single-user BasicAuth"):
        get_stdio_mcp()


@pytest.mark.unit
def test_get_stdio_mcp_registers_all_apps_by_default(single_user_env):
    """All app tool groups are registered when no filter is specified."""
    mcp = get_stdio_mcp()
    # NOTE: _tool_manager is a FastMCP internal; may break on SDK upgrades
    tools = mcp._tool_manager.list_tools()
    tool_names = {t.name for t in tools}

    # Spot-check representative tools from each app
    assert "nc_notes_get_note" in tool_names
    assert "nc_webdav_list_directory" in tool_names
    assert "nc_calendar_list_calendars" in tool_names
    assert "nc_contacts_list_addressbooks" in tool_names
    assert "nc_cookbook_list_recipes" in tool_names
    assert "deck_get_boards" in tool_names
    assert "nc_tables_list_tables" in tool_names
    assert "nc_share_list" in tool_names
    assert "nc_news_list_feeds" in tool_names
    assert "collectives_get_collectives" in tool_names


@pytest.mark.unit
def test_get_stdio_mcp_respects_enabled_apps(single_user_env):
    """Only specified apps have their tools registered."""
    mcp = get_stdio_mcp(enabled_apps=["notes"])
    # NOTE: _tool_manager is a FastMCP internal; may break on SDK upgrades
    tools = mcp._tool_manager.list_tools()
    tool_names = {t.name for t in tools}

    assert "nc_notes_get_note" in tool_names
    # Other apps should NOT be present
    assert "nc_webdav_list_directory" not in tool_names
    assert "nc_calendar_list_calendars" not in tool_names


@pytest.mark.unit
def test_get_stdio_mcp_no_semantic_tools(single_user_env):
    """Semantic search tools are never registered in stdio mode."""
    mcp = get_stdio_mcp()
    # NOTE: _tool_manager is a FastMCP internal; may break on SDK upgrades
    tools = mcp._tool_manager.list_tools()
    tool_names = {t.name for t in tools}

    semantic_names = [n for n in tool_names if "semantic" in n or "vector" in n]
    assert semantic_names == [], f"Unexpected semantic tools: {semantic_names}"


@pytest.mark.unit
def test_get_stdio_mcp_registers_capabilities_resource(single_user_env):
    """The nc://capabilities resource is registered."""
    mcp = get_stdio_mcp()
    # NOTE: _resource_manager._resources is a FastMCP internal; may break on SDK upgrades
    resources = mcp._resource_manager._resources
    assert "nc://capabilities" in resources
