from src.domain.app_blocks.composition_graph import (
    build_composition_graph,
    selected_composition_graph,
    validate_composition_graph,
)


def test_composition_graph_exposes_pack_block_primitive_edges():
    graph = build_composition_graph()

    assert graph["schema_version"] == 1
    assert graph["authority"]["app_blocks"] == "core_yaml"

    packs = {item["id"]: item for item in graph["packs"]}
    blocks = {item["id"]: item for item in graph["app_blocks"]}

    assert "contact-capture" in packs
    assert "forms.contact" in blocks
    assert "forms.contact" in packs["contact-capture"]["app_blocks"]
    assert {item["id"] for item in blocks["forms.contact"]["requires"]} >= {
        "form.public_create",
        "data.entity",
    }


def test_composition_graph_is_sorted_and_does_not_invent_edges():
    graph = build_composition_graph()

    assert [item["id"] for item in graph["packs"]] == sorted(
        item["id"] for item in graph["packs"]
    )
    assert [item["id"] for item in graph["app_blocks"]] == sorted(
        item["id"] for item in graph["app_blocks"]
    )
    assert all(
        dependency["kind"] in {"primitive", "feature_pack", "app_block"}
        for item in graph["app_blocks"]
        for dependency in item["requires"] + item["optional_requires"]
    )


def test_selected_composition_graph_retains_unresolved_ids_for_audits():
    graph = selected_composition_graph(
        app_block_ids=["auth.sign_in", "missing.block"],
        feature_pack_ids=["appointment-booking", "missing-pack"],
    )

    assert [item["id"] for item in graph["app_blocks"]] == ["auth.sign_in"]
    assert [item["id"] for item in graph["packs"]] == ["appointment-booking"]
    assert graph["unresolved"] == {
        "feature_packs": ["missing-pack"],
        "app_blocks": ["missing.block"],
    }
    assert validate_composition_graph(graph) == [
        "unresolved_app_blocks:missing.block",
        "unresolved_feature_packs:missing-pack",
    ]


def test_catalog_composition_graph_has_no_architecture_errors():
    assert validate_composition_graph(build_composition_graph()) == []
