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

Tests for transfer_ack, consumed sessions, and WS correlation envelope merge.
"""

from __future__ import annotations

from pathlib import Path

import pytest

from mcp_proxy_adapter.core.job_push.transfer_correlation import (
    merge_transfer_correlation_envelope,
)
from mcp_proxy_adapter.transfer import TransferAckError
from mcp_proxy_adapter.transfer import TransferSessionNotFoundError
from mcp_proxy_adapter.transfer.checksums import compute_file_checksum
from mcp_proxy_adapter.transfer.server_store import TransferServerStore


@pytest.fixture
def store(tmp_path: Path) -> TransferServerStore:
    root = tmp_path / "transfer_root"
    root.mkdir()
    return TransferServerStore(
        storage_dir=str(root),
        session_ttl_seconds=3600,
        max_file_size_bytes=10_000_000,
        default_chunk_size_bytes=1024,
        max_chunk_size_bytes=1024,
    )


def test_ack_fails_before_download_complete(
    store: TransferServerStore, tmp_path: Path
) -> None:
    files_dir = Path(store._storage_dir) / "files"
    files_dir.mkdir(parents=True, exist_ok=True)
    src = files_dir / "blob.bin"
    src.write_bytes(b"hello-world")
    receipt = store.create_download_session(
        str(src),
        "blob.bin",
        "sha256",
        "identity",
        job_id="job-a",
        delete_source_on_ack=True,
    )
    tid = receipt.transfer_id
    digest = compute_file_checksum(str(src))
    with pytest.raises(TransferAckError, match="not complete"):
        store.acknowledge_download_transfer(
            tid,
            checksum_algorithm="sha256",
            checksum_value=digest,
            job_id="job-a",
        )


def test_ack_idempotent_and_hides_session(
    store: TransferServerStore, tmp_path: Path
) -> None:
    files_dir = Path(store._storage_dir) / "files"
    files_dir.mkdir(parents=True, exist_ok=True)
    src = files_dir / "blob.bin"
    src.write_bytes(b"ack-test-bytes")
    receipt = store.create_download_session(
        str(src),
        "blob.bin",
        "sha256",
        "identity",
        job_id="job-b",
        delete_source_on_ack=True,
    )
    tid = receipt.transfer_id
    digest = compute_file_checksum(str(src))
    store.read_download_chunk(tid, 0, 10_000)
    out = store.acknowledge_download_transfer(
        tid,
        checksum_algorithm="sha256",
        checksum_value=digest,
        job_id="job-b",
    )
    assert out["success"] is True
    assert out.get("idempotent") is False
    out2 = store.acknowledge_download_transfer(
        tid,
        checksum_algorithm="sha256",
        checksum_value=digest,
        job_id="job-b",
    )
    assert out2.get("idempotent") is True
    with pytest.raises(TransferSessionNotFoundError):
        store.get_session(tid)


def test_correlation_envelope_merge(monkeypatch, store: TransferServerStore) -> None:
    from mcp_proxy_adapter.api import handlers as handlers_mod

    monkeypatch.setattr(handlers_mod, "get_transfer_store", lambda: store)
    files_dir = Path(store._storage_dir) / "files"
    files_dir.mkdir(parents=True, exist_ok=True)
    src2 = files_dir / "d.bin"
    src2.write_bytes(b"yy")
    dr = store.create_download_session(
        str(src2),
        "d.bin",
        "sha256",
        "identity",
        job_id="j2",
        correlation_id="c2",
        command="cmd",
        inbound_transfer_id="tr_in",
    )
    tid2 = dr.transfer_id
    merged = merge_transfer_correlation_envelope(
        tid2,
        {"direction": "download", "status": "created"},
    )
    assert merged.get("schema_version") == 1
    assert merged["job_id"] == "j2"
    assert merged["outbound_transfer_id"] == tid2
    assert merged["inbound_transfer_id"] == "tr_in"
    assert merged["correlation_id"] == "c2"
    assert merged["command"] == "cmd"
