"""
JSON-RPC roundtrip tests for transfer commands.

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

from __future__ import annotations

import hashlib
from pathlib import Path

import pytest
from fastapi.testclient import TestClient

import mcp_proxy_adapter.api.handlers as handlers
from mcp_proxy_adapter.api.app import create_app


@pytest.fixture
def transfer_client(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> TestClient:
    monkeypatch.setattr(
        "mcp_proxy_adapter.api.handlers.DEFAULT_STORAGE_DIR",
        str(tmp_path / "tstore"),
        raising=False,
    )
    handlers._CACHED_TRANSFER_STORE = None
    app = create_app(title="rt", description="rt", version="1.0.0")
    return TestClient(app)


def _rpc(client: TestClient, method: str, params: dict) -> dict:
    r = client.post(
        "/api/jsonrpc",
        json={"jsonrpc": "2.0", "method": method, "params": params, "id": 1},
    )
    assert r.status_code == 200, r.text
    return r.json()


def test_jsonrpc_transfer_upload_begin_returns_transfer_id_and_chunk_template(
    transfer_client: TestClient,
) -> None:
    digest = "b" * 64
    data = _rpc(
        transfer_client,
        "transfer_upload_begin",
        {
            "filename": "f.bin",
            "size_bytes": 10,
            "checksum_value": digest,
            "compression": "identity",
        },
    )
    result = data["result"]
    assert result["success"] is True
    d = result["data"]
    assert isinstance(d["transfer_id"], str) and d["transfer_id"]
    tpl = d.get("transport", {}).get("chunk_path_template", "")
    assert "/api/transfer/uploads/" in tpl


def test_jsonrpc_transfer_upload_status_roundtrip(transfer_client: TestClient) -> None:
    digest = "b" * 64
    begin = _rpc(
        transfer_client,
        "transfer_upload_begin",
        {
            "filename": "g.bin",
            "size_bytes": 3,
            "checksum_value": digest,
            "compression": "identity",
        },
    )
    tid = begin["result"]["data"]["transfer_id"]
    st = _rpc(
        transfer_client,
        "transfer_upload_status",
        {"transfer_id": tid},
    )
    assert st["result"]["success"] is True
    assert st["result"]["data"]["checksum_value"] == digest


def test_jsonrpc_transfer_upload_put_chunk_and_complete(
    transfer_client: TestClient,
) -> None:
    content = b"abc"
    digest = hashlib.sha256(content).hexdigest()
    begin = _rpc(
        transfer_client,
        "transfer_upload_begin",
        {
            "filename": "chunk.bin",
            "size_bytes": len(content),
            "checksum_value": digest,
            "compression": "identity",
        },
    )
    tid = begin["result"]["data"]["transfer_id"]
    put = transfer_client.put(
        f"/api/transfer/uploads/{tid}/chunks?offset=0",
        content=content,
    )
    assert put.status_code == 200, put.text
    done = _rpc(
        transfer_client,
        "transfer_upload_complete",
        {"transfer_id": tid},
    )
    assert done["result"]["success"] is True


def test_jsonrpc_transfer_download_begin_and_status(
    transfer_client: TestClient, tmp_path: Path
) -> None:
    src = tmp_path / "src.dat"
    src.write_bytes(b"hello-download")
    begin = _rpc(
        transfer_client,
        "transfer_download_begin",
        {
            "source_path": str(src.resolve()),
            "filename": "src.dat",
            "compression": "identity",
        },
    )
    assert begin["result"]["success"] is True
    tid = begin["result"]["data"]["transfer_id"]
    st = _rpc(
        transfer_client,
        "transfer_download_status",
        {"transfer_id": tid},
    )
    assert st["result"]["success"] is True
    assert st["result"]["data"].get("checksum_algorithm")
