"""Regression test for #136 — an unlinked digest citation must never be dropped
silently.

``_handle_unlinked_citation`` routes via the canonical classifier:
  * supreme/admin → a court-fetch job (no missing_precedent here — the X13
    orchestrator opens its own on failure),
  * skip (ערר/בל"מ) / unknown → a deduped missing_precedent (discovery_source
    'digest'), which previously vanished.

Runs OFFLINE — monkeypatches the db calls and records what each routing did.
"""

from __future__ import annotations

import asyncio

import pytest

from legal_mcp.services import digest_library as dl
from legal_mcp.services import db


class _Spy:
    def __init__(self):
        self.court_fetch = []
        self.created_mp = []
        self.find_mp_returns = None

    def install(self, monkeypatch):
        async def _job_upsert(**kw):
            self.court_fetch.append(kw)
        async def _find_mp(citation, case_id=None):
            return self.find_mp_returns
        async def _create_mp(**kw):
            self.created_mp.append(kw)
            return {"id": "mp"}
        async def _get_digest(_id):
            return {"yomon_number": "5167"}
        monkeypatch.setattr(db, "court_fetch_job_upsert", _job_upsert)
        monkeypatch.setattr(db, "find_missing_precedent_by_citation", _find_mp)
        monkeypatch.setattr(db, "create_missing_precedent", _create_mp)
        monkeypatch.setattr(db, "get_digest", _get_digest)


def _run(coro):
    loop = asyncio.new_event_loop()
    try:
        return loop.run_until_complete(coro)
    finally:
        loop.close()


@pytest.fixture()
def spy(monkeypatch):
    s = _Spy()
    s.install(monkeypatch)
    return s


_DID = "11111111-1111-1111-1111-111111111111"


def test_committee_citation_opens_missing_precedent(spy):
    _run(dl._handle_unlinked_citation(_DID, "ערר 1198-12-25 זאטוס"))
    assert spy.court_fetch == []                       # ערר is never auto-fetched
    assert len(spy.created_mp) == 1, spy.created_mp
    mp = spy.created_mp[0]
    assert mp["discovery_source"] == "digest"
    assert "יומון" in (mp["notes"] or "")             # provenance recorded


def test_court_verdict_enqueues_fetch_not_mp(spy):
    _run(dl._handle_unlinked_citation(_DID, 'עע"מ 3975/22 פלוני'))
    assert len(spy.court_fetch) == 1, spy.court_fetch
    assert spy.created_mp == []                        # fetchable → orchestrator owns its MP


def test_dedup_skips_existing_gap(spy):
    spy.find_mp_returns = {"id": "existing"}           # gap already recorded
    _run(dl._handle_unlinked_citation(_DID, "ערר 1192/18"))
    assert spy.created_mp == []                        # no duplicate


def test_unknown_citation_opens_missing_precedent(spy):
    _run(dl._handle_unlinked_citation(_DID, "משהו בלי ערכאה ברורה"))
    # unknown tier is not fetchable → must still surface as a gap, never dropped.
    assert spy.court_fetch == []
    assert len(spy.created_mp) == 1
