"""Regression tests for the write call-sites rewired onto storage.py (X14
Phase 2). They assert the rewired staging lands bytes at the exact legacy
on-disk location under the default filesystem backend — i.e. zero behaviour
change.
"""
import asyncio
from pathlib import Path

import pytest

from legal_mcp import config
from legal_mcp.services import ingest, storage


@pytest.fixture(autouse=True)
def _tmp_datadir(tmp_path, monkeypatch):
    monkeypatch.setattr(config, "DATA_DIR", tmp_path)
    monkeypatch.setattr(config, "STORAGE_BACKEND", "filesystem")
    storage.reset_storage_cache()
    yield tmp_path
    storage.reset_storage_cache()


def run(coro):
    return asyncio.run(coro)


def test_stage_file_lands_under_datadir(_tmp_datadir):
    src = _tmp_datadir / "src" / "כתב ערר.pdf"
    src.parent.mkdir(parents=True)
    src.write_bytes(b"%PDF-1.4 ...")
    root = _tmp_datadir / "precedent-library"
    # _stage_file returns the DATA_DIR-relative storage KEY (what the DB stores);
    # the caller resolves a local path via storage.ensure_local.
    key = run(ingest._stage_file(src, root, "court_ruling"))
    assert isinstance(key, str)
    assert key.startswith("precedent-library/court_ruling/")
    assert key.endswith(".pdf")
    # under the filesystem backend the key maps to the exact legacy on-disk path
    dest = _tmp_datadir / key
    assert dest.parent == root / "court_ruling"
    assert dest.exists()
    assert dest.read_bytes() == b"%PDF-1.4 ..."


def test_stage_file_default_subdir(_tmp_datadir):
    src = _tmp_datadir / "x.docx"
    src.write_bytes(b"doc")
    key = run(ingest._stage_file(src, _tmp_datadir / "digests", ""))
    dest = _tmp_datadir / key
    assert dest.parent == _tmp_datadir / "digests" / "other"
    assert dest.exists()


def test_thumbnail_renderer_routes_through_storage(_tmp_datadir):
    """extractor.render_pages_for_multimodal (a sync renderer) now persists the
    JPEG thumbnail via the sync storage facade — under filesystem it must land
    at the requested thumbnail_dir."""
    fitz = pytest.importorskip("fitz")
    from legal_mcp.services import extractor

    pdf = _tmp_datadir / "doc.pdf"
    d = fitz.open()
    d.new_page(width=200, height=200)
    d.save(str(pdf))
    d.close()

    thumb_dir = _tmp_datadir / "cases" / "1" / "thumbnails" / "docid"
    out = extractor.render_pages_for_multimodal(pdf, embed_dpi=72, thumb_dpi=36,
                                                thumbnail_dir=thumb_dir)
    assert len(out) == 1
    _img, thumb_path = out[0]
    assert thumb_path == thumb_dir / "p001.jpg"
    assert thumb_path.exists()  # written through storage.put_bytes_sync (DERIVED)
    assert thumb_path.read_bytes()[:2] == b"\xff\xd8"  # JPEG magic


def test_put_bytes_sync_roundtrip(_tmp_datadir):
    src_key = "cases/1/exports/x.docx"
    storage.put_bytes_sync(src_key, b"PK\x03\x04zip", bucket=storage.Bucket.DOCUMENTS)
    assert (_tmp_datadir / src_key).read_bytes() == b"PK\x03\x04zip"


def test_ascii_metadata_encodes_hebrew():
    """S3 object metadata must be ASCII (botocore enforces). A Hebrew original
    filename — the value ingest._stage_file attaches — must come back ASCII and
    losslessly recoverable (regression: s3-only digest/document upload 500)."""
    from urllib.parse import unquote
    name = "יומון 5167 - 11.6.26.pdf"
    out = storage._ascii_metadata(name)
    assert out.isascii()
    assert unquote(out) == name
    # plain ASCII passes through untouched (readability)
    assert storage._ascii_metadata("digest_ab12.pdf") == "digest_ab12.pdf"


def test_s3_put_bytes_sends_ascii_metadata(monkeypatch):
    """Reproduce the failure path: S3Backend.put_bytes with a Hebrew filename in
    metadata must hand put_object an ASCII-only Metadata mapping (no
    ParamValidationError)."""
    captured = {}

    class _FakeS3:
        async def put_object(self, **kwargs):
            captured.update(kwargs)
            return {}

    class _FakeClientCtx:
        async def __aenter__(self):
            return _FakeS3()
        async def __aexit__(self, *exc):
            return False

    backend = storage.S3Backend()
    monkeypatch.setattr(backend, "_client", lambda **kw: _FakeClientCtx())
    monkeypatch.setattr(storage, "_bucket_name", lambda b: "documents")

    run(backend.put_bytes(
        "digests/incoming/ab12_x.pdf", b"%PDF-1.4",
        bucket=storage.Bucket.DOCUMENTS,
        metadata={"filename": "יומון 5167 - 11.6.26.pdf"},
    ))
    meta = captured["Metadata"]
    assert all(v.isascii() for v in meta.values())
    from urllib.parse import unquote
    assert unquote(meta["filename"]) == "יומון 5167 - 11.6.26.pdf"
