"""Characterization tests for the Domain Knowledge Program v1 backlog (data, not code).

Pins the program FRAMEWORK contract: a ranked backlog of domain definitions, each entered by INDUSTRY
with its typical requirement sources + a pre-onboarding capability hypothesis (typical_certifications).
Industrial Automation is rank 1. Environmental stays law-first. If a future edit reorders the backlog,
drops a source list, or reverts environmental to an ISO-first framing, these tests fail.
"""

from __future__ import annotations

import os

import yaml

_DIR = os.path.join(os.path.dirname(__file__), "..", "knowledge", "programs")


def _programs():
    out = {}
    for f in sorted(os.listdir(_DIR)):
        if f.endswith(".yaml"):
            with open(os.path.join(_DIR, f), encoding="utf-8") as h:
                p = yaml.safe_load(h)
            if "backlog_rank" in p:                                    # domain programs only (not transitions backlog)
                out[p["id"]] = p
    return out


def _transitions():
    with open(os.path.join(_DIR, "transitions.yaml"), encoding="utf-8") as h:
        return yaml.safe_load(h)


def test_five_domains_ranked_backlog():
    ranks = sorted(p["backlog_rank"] for p in _programs().values())
    assert ranks == [1, 2, 3, 4, 5]


def test_industrial_automation_is_rank_1():
    progs = _programs()
    rank1 = [p for p in progs.values() if p["backlog_rank"] == 1]
    assert len(rank1) == 1 and rank1[0]["id"] == "PROG-industrial-automation"
    assert {"CRA", "MaschinenVO"} <= set(rank1[0]["typical_requirement_sources"])


def test_every_domain_entered_by_industry_with_sources_and_hypothesis():
    for p in _programs().values():
        assert p.get("industry") and p.get("customer_entry")           # industry-first entry
        assert p["typical_requirement_sources"]                         # stage 2 defined
        assert p["typical_certifications"]                             # pre-onboarding capability hypothesis (ETO)


def test_no_stored_stage_status_progress_is_derived():
    # the 7-stage progress is computed-not-stored: program shells must NOT hard-code stage status
    for p in _programs().values():
        assert "stages" not in p


def test_environmental_stays_law_first():
    env = _programs()["PROG-environmental"]
    assert "ISO 14001 ist KEIN Umweltrecht" in env["principle"]
    assert set(env["typical_requirement_sources"]) == {"water", "chemicals", "emissions", "energy", "waste", "product_responsibility"}


def test_automotive_and_medical_present():
    progs = _programs()
    assert "TISAX" in progs["PROG-automotive"]["typical_requirement_sources"]
    assert "MDR" in progs["PROG-medical"]["typical_requirement_sources"]


def test_readme_documents_seven_stage_checklist():
    with open(os.path.join(_DIR, "README.md"), encoding="utf-8") as h:
        readme = h.read()
    for stage in ["Domain Model", "Requirement Sources", "Capability Registry",
                  "Transition Patterns", "Playbooks", "Reference Scenarios", "Completeness"]:
        assert stage in readme
    assert "Industrial Automation" in readme                            # backlog #1 documented


def test_transition_backlog_has_top_demanded_transitions():
    ts = _transitions()["transitions"]
    pairs = {(t["from"], t["to"]) for t in ts}
    # the highest-value transitions customers actually buy
    assert ("ISO27001", "CRA") in pairs and ("ISO9001", "CRA") in pairs
    assert ("ISO9001", "MaschinenVO") in pairs


def test_transition_backlog_is_prioritised():
    ts = _transitions()["transitions"]
    for t in ts:
        assert 1 <= t["priority"] <= 5 and t["from"] and t["to"]
    # the five-star transitions are the CRA/MaschinenVO entry points
    five = {(t["from"], t["to"]) for t in ts if t["priority"] == 5}
    assert ("ISO9001", "MaschinenVO") in five


def test_transition_is_the_unit_documented():
    with open(os.path.join(_DIR, "README.md"), encoding="utf-8") as h:
        readme = h.read()
    assert "unit of knowledge is the TRANSITION" in readme
    assert "Operational Knowledge" in readme and "Verification Knowledge" in readme   # three layers
