"""HTTP transfer route integration tests (FastAPI TestClient).

Author: Vasiliy Zdanovskiy
email: vasilyvz@gmail.com

Branch gate: adapter pipeline must still run transfer_compatibility_and_real_server_validation
(large-file transfer, large-result download, full protocol/auth/access matrix). These tests are
in-process only and do not replace that gate.
"""

from __future__ import annotations

from typing import Any

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient

from mcp_proxy_adapter.api.core.app_factory_routes import setup_routes
from mcp_proxy_adapter.commands.builtin_commands import register_builtin_commands
from mcp_proxy_adapter.transfer.server_store import TransferServerStore

PAYLOAD = b"hello world!"
EXPECTED_SHA256 = (
    "7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9"
)


@pytest.fixture
def transfer_app_client(tmp_path: Any, monkeypatch: pytest.MonkeyPatch) -> TestClient:
    from mcp_proxy_adapter.api import handlers as handlers_mod

    store = TransferServerStore(
        storage_dir=str(tmp_path / "tstore"),
        session_ttl_seconds=3600,
        max_file_size_bytes=10737418240,
        default_chunk_size_bytes=1048576,
        max_chunk_size_bytes=8388608,
    )
    monkeypatch.setattr(handlers_mod, "_CACHED_TRANSFER_STORE", None)
    monkeypatch.setattr(handlers_mod, "get_transfer_store", lambda: store)

    app = FastAPI()
    register_builtin_commands()
    setup_routes(app)
    return TestClient(app)


def test_transfer_routes_are_registered_in_fastapi_app(
    transfer_app_client: TestClient,
) -> None:
    routes = {r.path for r in transfer_app_client.app.routes}
    assert "/api/transfer/uploads" in routes
    assert "/api/transfer/uploads/{transfer_id}" in routes
    assert "/api/transfer/uploads/{transfer_id}/chunks" in routes
    assert "/api/transfer/uploads/{transfer_id}/complete" in routes
    assert "/api/transfer/downloads" in routes
    assert "/api/transfer/downloads/{transfer_id}" in routes
    assert "/api/transfer/downloads/{transfer_id}/chunks" in routes


def test_create_upload_session_returns_receipt(
    transfer_app_client: TestClient,
) -> None:
    r = transfer_app_client.post(
        "/api/transfer/uploads",
        json={
            "filename": "blob.bin",
            "size_bytes": len(PAYLOAD),
            "checksum_algorithm": "sha256",
            "checksum_value": EXPECTED_SHA256,
            "compression": "identity",
            "chunk_size": 4,
        },
    )
    assert r.status_code == 201
    body = r.json()
    assert body["transfer_id"]
    assert body["offset"] == 0
    assert body["completed"] is False


def test_upload_chunk_returns_updated_receipt(
    transfer_app_client: TestClient,
) -> None:
    c = transfer_app_client.post(
        "/api/transfer/uploads",
        json={
            "filename": "blob.bin",
            "size_bytes": len(PAYLOAD),
            "checksum_algorithm": "sha256",
            "checksum_value": EXPECTED_SHA256,
            "compression": "identity",
            "chunk_size": 4,
        },
    )
    tid = c.json()["transfer_id"]
    u = transfer_app_client.put(
        f"/api/transfer/uploads/{tid}/chunks?offset=0",
        content=PAYLOAD[0:4],
    )
    assert u.status_code == 200
    assert u.json()["offset"] == 4


def test_complete_upload_session_returns_completed_receipt(
    transfer_app_client: TestClient,
) -> None:
    c = transfer_app_client.post(
        "/api/transfer/uploads",
        json={
            "filename": "blob.bin",
            "size_bytes": len(PAYLOAD),
            "checksum_algorithm": "sha256",
            "checksum_value": EXPECTED_SHA256,
            "compression": "identity",
            "chunk_size": 4,
        },
    )
    tid = c.json()["transfer_id"]
    off = 0
    while off < len(PAYLOAD):
        chunk = PAYLOAD[off:off + 4]
        transfer_app_client.put(
            f"/api/transfer/uploads/{tid}/chunks?offset={off}",
            content=chunk,
        )
        off += len(chunk)
    fin = transfer_app_client.post(f"/api/transfer/uploads/{tid}/complete")
    assert fin.status_code == 200
    body = fin.json()
    assert body["completed"] is True
    assert body["status"] == "uploaded"


def test_create_download_session_and_download_chunk(
    tmp_path: Any,
    transfer_app_client: TestClient,
) -> None:
    src = tmp_path / "dl_src.bin"
    src.write_bytes(PAYLOAD)
    c = transfer_app_client.post(
        "/api/transfer/downloads",
        json={
            "source_path": str(src),
            "filename": "dl_src.bin",
            "compression": "identity",
            "checksum_algorithm": "sha256",
        },
    )
    assert c.status_code == 201
    tid = c.json()["transfer_id"]

    g = transfer_app_client.get(
        f"/api/transfer/downloads/{tid}/chunks",
        params={"offset": 0, "limit": 1024},
    )
    assert g.status_code == 200
    assert g.content == PAYLOAD
    assert g.headers.get("X-Transfer-Id") == tid
    assert g.headers.get("X-Transfer-Completed", "").lower() == "true"
