"""Async command path preserves transfer_id metadata (no raw bytes in payloads).

Author: Vasiliy Zdanovskiy
email: vasilyvz@gmail.com
"""

from __future__ import annotations

from unittest.mock import AsyncMock, MagicMock

import pytest
from fastapi import FastAPI, Request

from mcp_proxy_adapter.api.core.app_factory_routes import setup_routes
from mcp_proxy_adapter.api.handlers_async import (
    _run_async_command_and_notify,
    execute_command_async,
)
from mcp_proxy_adapter.commands.builtin_commands import register_builtin_commands
from mcp_proxy_adapter.core.delivery.terminal_replay_store import TerminalReplayStore
from mcp_proxy_adapter.core.delivery.ws_delivery_manager import WsDeliveryManager
from mcp_proxy_adapter.core.errors import InvalidRequestError
from mcp_proxy_adapter.core.job_push.subscriptions import SubscriberRegistry


def _make_app() -> FastAPI:
    app = FastAPI()
    register_builtin_commands()
    setup_routes(app)
    registry = SubscriberRegistry()
    replay = TerminalReplayStore()
    manager = WsDeliveryManager(registry, replay)
    app.state.ws_delivery_manager = manager
    return app


@pytest.mark.asyncio
async def test_execute_async_preserves_transfer_id_in_acceptance_payload() -> None:
    app = _make_app()
    mock_request = MagicMock(spec=Request)
    mock_request.app = app
    mock_request.state = MagicMock()

    result = await execute_command_async(
        "echo",
        {
            "message": "hi",
            "transfer_id": "tr_100",
            "filename": "input.md",
        },
        None,
        request_id="t1",
        request=mock_request,
    )
    assert result["accepted"] is True
    assert result["transfer_id"] == "tr_100"
    assert result["filename"] == "input.md"


@pytest.mark.asyncio
async def test_async_notification_payload_keeps_transfer_id_when_present() -> None:
    app = _make_app()
    manager = app.state.ws_delivery_manager
    received: list[dict] = []

    async def capture(ws_id: str, payload: dict) -> None:
        received.append({"ws_id": ws_id, "payload": payload})

    manager.notify_terminal_delivery = AsyncMock(side_effect=capture)

    from mcp_proxy_adapter.commands.command_registry import registry

    echo_cls = registry.get_command("echo")
    ws_id = manager.issue_ws_id()
    await _run_async_command_and_notify(
        echo_cls,
        "echo",
        {"message": "x", "transfer_id": "tr_200"},
        {},
        ws_id,
        manager,
        logger=MagicMock(),
    )

    assert received, "expected terminal delivery"
    assert received[0]["payload"].get("transfer_id") == "tr_200"


@pytest.mark.asyncio
async def test_async_flow_never_embeds_raw_file_bytes() -> None:
    app = _make_app()
    mock_request = MagicMock(spec=Request)
    mock_request.app = app
    mock_request.state = MagicMock()

    with pytest.raises(InvalidRequestError):
        await execute_command_async(
            "echo",
            {"message": "x", "transfer_id": "tr_300", "blob": b"\x00\x01"},
            None,
            request_id="t3",
            request=mock_request,
        )
