"""FU-7: audit-trail + provenance (offline, monkeypatched I/O)."""
from __future__ import annotations

import asyncio
from uuid import uuid4

import pytest

from legal_mcp.services import audit, db


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


# ── GAP-18: log_action_safe is non-fatal ───────────────────────────────
def test_log_action_safe_swallows_db_error(monkeypatch):
    async def _boom(*a, **k):
        raise RuntimeError("db down")
    monkeypatch.setattr(audit, "log_action", _boom)
    # must NOT raise
    _run(audit.log_action_safe("write_block", details={"x": 1}))


def test_log_action_safe_forwards_args(monkeypatch):
    seen = {}
    async def _capture(action, case_id=None, document_id=None, details=None, user="system"):
        seen.update(action=action, details=details)
    monkeypatch.setattr(audit, "log_action", _capture)
    _run(audit.log_action_safe("export_docx", details={"path": "/x"}))
    assert seen["action"] == "export_docx" and seen["details"] == {"path": "/x"}


# ── GAP-20: structural citation resolver ────────────────────────────────
def test_resolve_citation_case_law_ids_splits(monkeypatch):
    good = uuid4()
    bad = uuid4()

    class _Conn:
        async def fetchval(self, q, cid):
            return cid == good
        async def __aenter__(self): return self
        async def __aexit__(self, *a): return False

    class _Pool:
        def acquire(self): return _Conn()

    async def _pool():
        return _Pool()
    monkeypatch.setattr(db, "get_pool", _pool)

    out = _run(db.resolve_citation_case_law_ids([good, bad]))
    assert good in out["resolved"] and bad in out["unresolved"]


# ── GAP-17: blocks_stale helper ────────────────────────────────────────
def test_mark_blocks_stale_executes_update(monkeypatch):
    seen = {}

    class _Conn:
        async def execute(self, q, *a):
            seen["q"] = q; seen["args"] = a
        async def __aenter__(self): return self
        async def __aexit__(self, *a): return False

    class _Pool:
        def acquire(self): return _Conn()

    async def _pool(): return _Pool()
    monkeypatch.setattr(db, "get_pool", _pool)

    cid = uuid4()
    _run(db.mark_blocks_stale(cid, True))
    assert "blocks_stale" in seen["q"] and seen["args"][0] is True and seen["args"][1] == cid
