"""Tests for context API endpoints: /v1/context/*, /v1/sessions, /v1/mcp/servers."""

from unittest.mock import MagicMock, patch

import pytest


class TestReceiveDelta:
    """Tests for POST /v1/context/delta endpoint."""

    def test_valid_delta_accepted(self, authed_client, valid_delta_payload):
        """Valid delta payload is accepted."""
        with patch("proxym.api.context_api.DeltaBuffer") as mock_buffer:
            mock_buffer.compute_delta.return_value = MagicMock(
                success=True,
                tokens_added=100,
            )

            response = authed_client.post(
                "/v1/context/delta",
                json=valid_delta_payload,
            )

        assert response.status_code == 200
        data = response.json()
        assert data.get("success") is True

    def test_invalid_delta_returns_400(self, authed_client):
        """Invalid delta payload returns 400."""
        response = authed_client.post(
            "/v1/context/delta",
            json={
                # Missing required fields
                "project_id": "test",
            },
        )

        assert response.status_code == 400

    def test_delta_updates_context_stats(self, authed_client, valid_delta_payload):
        """Delta updates context statistics."""
        with patch("proxym.api.context_api.get_context_store") as mock_store:
            mock_store.return_value = MagicMock(
                update_project=MagicMock(return_value=True),
                get_stats=MagicMock(return_value={
                    "files_tracked": 1,
                    "tokens_total": 150,
                    "version": 2,
                }),
            )

            response = authed_client.post(
                "/v1/context/delta",
                json=valid_delta_payload,
            )

        assert response.status_code == 200


class TestDetectContext:
    """Tests for context detection from project paths."""

    def test_detects_python_project_from_paths(self, authed_client):
        """Detects Python project from file paths."""
        response = authed_client.post(
            "/v1/context/detect",
            json={
                "paths": ["/home/dev/project/src/main.py", "/home/dev/project/pyproject.toml"],
            },
        )

        assert response.status_code == 200
        data = response.json()
        # Should detect Python stack
        assert "stack" in data or "language" in data

    def test_detects_stack_from_system_prompt(self, authed_client):
        """Detects stack from system prompt content."""
        response = authed_client.post(
            "/v1/context/detect",
            json={
                "system_prompt": "You are a TypeScript expert working with React and Node.js",
            },
        )

        assert response.status_code == 200
        data = response.json()
        # Should detect TypeScript/React stack
        assert "stack" in data or "frameworks" in data

    def test_returns_empty_context_when_no_signals(self, authed_client):
        """Returns empty context when no detection signals."""
        response = authed_client.post(
            "/v1/context/detect",
            json={
                "paths": ["/home/dev/unknown/file.txt"],
            },
        )

        assert response.status_code == 200
        data = response.json()
        # Should handle unknown context gracefully
        assert "error" not in data or data.get("context") is None


class TestListSessions:
    """Tests for /v1/sessions endpoint."""

    def test_empty_on_startup(self, authed_client):
        """Sessions list is empty on fresh startup."""
        with patch("proxym.api.context_api.get_session_store") as mock_store:
            mock_store.return_value = MagicMock(
                list_sessions=MagicMock(return_value=[]),
            )

            response = authed_client.get("/v1/sessions")

        assert response.status_code == 200
        data = response.json()
        assert data.get("sessions", []) == []

    def test_session_created_after_completion(self, authed_client):
        """Session is created after completion request."""
        with patch("proxym.api.context_api.get_session_store") as mock_store:
            mock_store.return_value = MagicMock(
                get_or_create=MagicMock(return_value=MagicMock(
                    id="sess-test-123",
                    history=[],
                    created_at="2024-01-01T00:00:00",
                )),
                list_sessions=MagicMock(return_value=[
                    {"id": "sess-test-123", "message_count": 1},
                ]),
            )

            response = authed_client.get("/v1/sessions")

        assert response.status_code == 200
        data = response.json()
        assert len(data.get("sessions", [])) > 0


class TestListMCPServers:
    """Tests for /v1/mcp/servers endpoint."""

    def test_returns_registered_servers(self, authed_client, mock_mcp_registry):
        """Returns list of registered MCP servers."""
        with patch("proxym.api.context_api.get_mcp_registry") as mock_registry:
            mock_registry.return_value = mock_mcp_registry

            response = authed_client.get("/v1/mcp/servers")

        assert response.status_code == 200
        data = response.json()
        assert "servers" in data
        assert isinstance(data["servers"], list)
        assert len(data["servers"]) == 2

    def test_empty_when_no_servers_configured(self, authed_client):
        """Returns empty list when no MCP servers configured."""
        with patch("proxym.api.context_api.get_mcp_registry") as mock_registry:
            mock_registry.return_value = {}

            response = authed_client.get("/v1/mcp/servers")

        assert response.status_code == 200
        data = response.json()
        assert data.get("servers", []) == []


class TestContextStats:
    """Tests for /v1/context/stats endpoint."""

    def test_returns_context_statistics(self, authed_client):
        """Returns context buffer statistics."""
        with patch("proxym.api.context_api.get_context_store") as mock_store:
            mock_store.return_value = MagicMock(
                get_stats=MagicMock(return_value={
                    "projects_tracked": 3,
                    "files_tracked": 42,
                    "tokens_total": 15000,
                    "version": 123,
                }),
            )

            response = authed_client.get("/v1/context/stats")

        assert response.status_code == 200
        data = response.json()
        assert "projects_tracked" in data
        assert "files_tracked" in data
        assert "tokens_total" in data
