"""FL-D6 audit: prove Codegen consumes canonical composition metadata.

This is a contract audit, not a claim that every declared application has been
deployed. Runtime deployment remains a separate proof dimension.
"""

from __future__ import annotations

from dataclasses import dataclass

from src.domain.app_blocks.canonical import CANONICAL_BLOCK_IDS
from src.domain.app_blocks.execution import assert_install_plan_installable
from src.domain.app_blocks.generated_product_conformance_12h import (
    ARCHETYPES,
    STARTERS,
    certification_fixture,
    compile_cert_plan,
)
from src.domain.app_blocks.catalogs import default_known_packs
from src.domain.codegen.prompt_wrapper import build_system_prompt
from src.domain.starter_library.catalog import known_contract_ids


@dataclass(frozen=True)
class CodegenReuseAudit:
    certification_cells: int
    canonical_plans: int
    authority_markers: tuple[str, ...]
    failures: tuple[str, ...] = ()

    @property
    def passed(self) -> bool:
        return not self.failures


def audit_codegen_canonical_reuse() -> CodegenReuseAudit:
    failures: list[str] = []
    authority = build_system_prompt("react_app", "Build the requested application.")
    required_markers = (
        "Composition authority",
        "validated App Block / Feature Pack composition",
        "Do not invent:",
        "planned App Blocks",
    )
    for marker in required_markers:
        if marker not in authority:
            failures.append(f"missing_prompt_authority:{marker}")

    canonical_plans = 0
    for archetype in ARCHETYPES:
        plan = compile_cert_plan(certification_fixture(archetype))
        try:
            assert_install_plan_installable(plan)
        except Exception as exc:  # noqa: BLE001 - audit reports the exact cell
            failures.append(f"uninstallable_plan:{archetype}:{exc}")
        unknown_blocks = sorted({item.id for item in plan.blocks} - set(CANONICAL_BLOCK_IDS))
        unknown_packs = sorted(set(plan.required_feature_packs) - set(default_known_packs()))
        unknown_contracts = sorted(set(plan.starter_contracts) - set(known_contract_ids()))
        for item in unknown_blocks:
            failures.append(f"unknown_app_block:{archetype}:{item}")
        for item in unknown_packs:
            failures.append(f"unknown_feature_pack:{archetype}:{item}")
        for item in unknown_contracts:
            failures.append(f"unknown_starter_contract:{archetype}:{item}")
        # Certification fixtures intentionally exercise the install compiler
        # directly rather than a vertical recipe. Their canonical identity is
        # the fixture's declared block/pack/starter closure.
        canonical_plans += 1

    return CodegenReuseAudit(
        certification_cells=len(ARCHETYPES) * len(STARTERS),
        canonical_plans=canonical_plans,
        authority_markers=required_markers,
        failures=tuple(failures),
    )


def assert_codegen_canonical_reuse() -> CodegenReuseAudit:
    audit = audit_codegen_canonical_reuse()
    if not audit.passed:
        raise AssertionError("; ".join(audit.failures))
    return audit
