"""Provenance helpers — the second axis of the three-layer wiki model.

Wiki pages have three orthogonal dimensions:

1. **entity_type** — what the page is ABOUT (person, organization, concept,
   event, place, document, decision).
2. **provenance** — how this knowledge GOT HERE (ingested, compiled,
   researched, manual, reflected).
3. **status** — where the page is in its LIFECYCLE (draft, verified,
   contested, superseded, retracted).

Before Cut 1 (session 2026-04-24) the first two axes were conflated —
``source_summary``/``synthesis``/``decision_record`` were entity_types even
though they described provenance. This module is the additive read-side
bridge that accepts BOTH signals so legacy pages keep working while the
migration to the clean three-layer model lands.

**Read-side rule**: prefer ``provenance`` when present, fall back to
legacy entity_type markers. Every helper here is defensive — missing
metadata yields ``False``, never raises.

Cut 2 (future) will migrate vault pages to the clean model and collapse
the legacy checks out of these helpers — until then, both signals are
checked.
"""

from __future__ import annotations

from typing import Any

__all__ = [
    "get_provenance",
    "is_raw_ingested",
    "is_compiled",
    "is_structural",
    "is_researched",
    "is_manual",
]


# ── Legacy entity_types that are really provenance markers ──
# These were modeled as entity_types before Cut 1. Pages with these values
# in frontmatter should be read as having the corresponding provenance.
_LEGACY_ENTITY_TO_PROVENANCE: dict[str, str] = {  # arch:deterministic — frozen Cut-1 backward-compat migration map; legacy values are not user strategy
    "source_summary": "ingested",
    "synthesis": "compiled",
    "decision_record": "reflected",
}


def get_provenance(meta: dict[str, Any] | None) -> str:
    """Resolve the provenance of a page from its frontmatter.

    Preference order: explicit ``provenance`` field wins. If absent,
    infer from the legacy entity_type markers. Returns ``""`` when
    neither signal is present (pre-Cut-1 pages that never carried
    either field).
    """
    if not meta:
        return ""
    prov = str(meta.get("provenance") or "").strip().lower()
    if prov:
        return prov
    etype = str(meta.get("entity_type") or "").strip().lower()
    return _LEGACY_ENTITY_TO_PROVENANCE.get(etype, "")


def is_raw_ingested(meta: dict[str, Any] | None) -> bool:
    """True if the page is a raw per-source summary.

    Accepts either ``provenance=ingested`` (new model) OR
    ``entity_type=source_summary`` (legacy).
    """
    return get_provenance(meta) == "ingested"


def is_compiled(meta: dict[str, Any] | None) -> bool:
    """True if the page was compiled by the editor from source summaries.

    Includes both single-source entity pages (person/org/concept pages
    created during compile) AND multi-source synthesis pages.
    """
    return get_provenance(meta) == "compiled"


def is_structural(meta: dict[str, Any] | None) -> bool:
    """True if the page is a structural/meta decision about the wiki itself.

    Accepts either ``provenance=reflected`` (new model) OR
    ``entity_type=decision_record`` (legacy).
    """
    return get_provenance(meta) == "reflected"


def is_researched(meta: dict[str, Any] | None) -> bool:
    """True if the page was written by the researcher answering a query."""
    return get_provenance(meta) == "researched"


def is_manual(meta: dict[str, Any] | None) -> bool:
    """True if the page was created manually by the user."""
    return get_provenance(meta) == "manual"
