"""Tests for MCP Server plugin — tool listing, execution, config.

Tests Task 5.16 acceptance criteria.
"""

from __future__ import annotations

import pytest

from tests.conftest import ORIGIN_HEADER


# ─── AC1: List MCP tools ───


@pytest.mark.asyncio
async def test_ac1_list_mcp_tools(mcp_authed_client):
    """AC1: GET /api/v1/mcp/tools → 200 + tool list with 9 tools."""
    client, _ = mcp_authed_client
    resp = await client.get("/api/v1/mcp/tools", headers=ORIGIN_HEADER)
    assert resp.status_code == 200
    data = resp.json()
    assert data["count"] == 9
    assert len(data["tools"]) == 9
    tool_names = [t["name"] for t in data["tools"]]
    assert "search_contacts" in tool_names
    assert "get_contact" in tool_names
    assert "create_contact" in tool_names
    assert "list_calendar_entries" in tool_names
    assert "create_calendar_entry" in tool_names
    assert "list_emails" in tool_names
    assert "send_email" in tool_names
    assert "list_files" in tool_names
    assert "upload_file" in tool_names


# ─── AC2: Get MCP config ───


@pytest.mark.asyncio
async def test_ac2_get_mcp_config(mcp_authed_client):
    """AC2: GET /api/v1/mcp/config → 200 + server config."""
    client, _ = mcp_authed_client
    resp = await client.get("/api/v1/mcp/config", headers=ORIGIN_HEADER)
    assert resp.status_code == 200
    data = resp.json()
    assert data["server_name"] == "LeoCRM"
    assert data["server_version"] == "1.0.0"
    assert data["protocol_version"] == "2024-11-05"
    assert data["auth_method"] == "api-token"
    assert "search_contacts" in data["available_tools"]
    assert len(data["available_tools"]) == 9


# ─── AC3: Execute search_contacts tool ───


@pytest.mark.asyncio
async def test_ac3_execute_search_contacts(mcp_authed_client):
    """AC3: POST /api/v1/mcp/tools/search_contacts/execute → 200 + results."""
    client, _ = mcp_authed_client
    resp = await client.post(
        "/api/v1/mcp/tools/search_contacts/execute",
        json={"arguments": {"query": "Admin", "limit": 10}},
        headers=ORIGIN_HEADER,
    )
    assert resp.status_code == 200
    data = resp.json()
    assert data["tool"] == "search_contacts"
    assert data["success"] is True
    assert "result" in data
    assert "contacts" in data["result"]


# ─── AC4: Execute non-existent tool returns 404 ───


@pytest.mark.asyncio
async def test_ac4_execute_nonexistent_tool(mcp_authed_client):
    """AC4: POST /api/v1/mcp/tools/nonexistent/execute → 404."""
    client, _ = mcp_authed_client
    resp = await client.post(
        "/api/v1/mcp/tools/nonexistent_tool/execute",
        json={"arguments": {}},
        headers=ORIGIN_HEADER,
    )
    assert resp.status_code == 404
    assert "tool_not_found" in resp.text


# ─── AC5: Tool definitions have correct schema ───


@pytest.mark.asyncio
async def test_ac5_tool_definitions_schema(mcp_authed_client):
    """AC5: GET /api/v1/mcp/tools → tools have proper schema with parameters."""
    client, _ = mcp_authed_client
    resp = await client.get("/api/v1/mcp/tools", headers=ORIGIN_HEADER)
    assert resp.status_code == 200
    tools = resp.json()["tools"]

    # Check search_contacts has query and limit params
    search_tool = next(t for t in tools if t["name"] == "search_contacts")
    param_names = [p["name"] for p in search_tool["parameters"]]
    assert "query" in param_names
    assert "limit" in param_names
    query_param = next(p for p in search_tool["parameters"] if p["name"] == "query")
    assert query_param["required"] is True

    # Check create_contact has name, email, phone, type params
    create_tool = next(t for t in tools if t["name"] == "create_contact")
    create_params = [p["name"] for p in create_tool["parameters"]]
    assert "name" in create_params
    assert "email" in create_params
    assert "phone" in create_params
    assert "type" in create_params


# ─── AC6: Unauthorized access is rejected ───


@pytest.mark.asyncio
async def test_ac6_unauthorized_access(mcp_client_fixture):
    """AC6: GET /api/v1/mcp/tools without auth → 401."""
    resp = await mcp_client_fixture.get("/api/v1/mcp/tools", headers=ORIGIN_HEADER)
    assert resp.status_code == 401


# ─── AC7: Execute create_contact tool ───


@pytest.mark.asyncio
async def test_ac7_execute_create_contact(mcp_authed_client):
    """AC7: POST /api/v1/mcp/tools/create_contact/execute → 200 + created contact."""
    client, _ = mcp_authed_client
    resp = await client.post(
        "/api/v1/mcp/tools/create_contact/execute",
        json={"arguments": {"name": "MCP Test Contact", "email": "mcp@test.com", "phone": "+49123456789", "type": "person"}},
        headers=ORIGIN_HEADER,
    )
    assert resp.status_code == 200
    data = resp.json()
    assert data["tool"] == "create_contact"
    assert data["success"] is True
    assert data["result"]["name"] == "MCP Test Contact"
    assert data["result"]["email"] == "mcp@test.com"
