import json

from src.domain.codegen.composition_manifest import materialize_core_composition


def test_materialize_core_composition_writes_plan_and_protects_required_packs(tmp_path):
    root = tmp_path / "repo"
    packs = root / "p2hs"
    packs.mkdir(parents=True)
    (packs / "feature-packs.json").write_text(
        json.dumps(
            {
                "version": 1,
                "install": [
                    {"pack_slug": "agent-extra", "config": {"enabled": True}}
                ],
                "compose": [{"name": "provider-owned-extra"}],
            }
        ),
        encoding="utf-8",
    )
    generation_plan = {
        "composition": {
            "app_block_ids": ["auth.profile", "auth.sign_in", "booking.appointment"],
            "feature_pack_ids": ["appointment-booking"],
            "primitive_ids": ["auth.roles", "booking.availability"],
            "cloud_capability_ids": ["authenticated_sign_in"],
        },
        "runtime": {
            "runtime_dependencies": [],
            "starter_contract_ids": ["record.table"],
        },
    }

    materialize_core_composition(root, generation_plan)

    app_plan = json.loads((packs / "app-blocks-plan.json").read_text(encoding="utf-8"))
    assert json.loads(
        (packs / "generation-plan.json").read_text(encoding="utf-8")
    ) == generation_plan
    assert {item["id"] for item in app_plan["blocks"]} == {
        "auth.profile",
        "auth.sign_in",
        "booking.appointment",
    }
    assert app_plan["required_feature_packs"] == ["appointment-booking"]
    assert (packs / "starter-contracts.json").exists()
    assert (packs / "app-block-hosts.json").exists()
    core = json.loads((packs / "core-composition.json").read_text(encoding="utf-8"))
    assert core["composition"]["app_block_ids"] == [
        "auth.profile",
        "auth.sign_in",
        "booking.appointment",
    ]
    assert core["composition_graph"]["scope"] == "selected_composition"
    assert {
        item["id"] for item in core["composition_graph"]["app_blocks"]
    } == {
        "auth.profile",
        "auth.sign_in",
        "booking.appointment",
    }
    assert core["composition_graph"]["unresolved"] == {
        "feature_packs": [],
        "app_blocks": [],
    }
    assert core["composition_graph_validation"] == {"valid": True, "errors": []}
    l3 = json.loads((packs / "l3-plan.json").read_text(encoding="utf-8"))
    assert l3["architecture_auto_promotion"] is False
    assert l3["candidates"] == []

    feature_packs = json.loads(
        (packs / "feature-packs.json").read_text(encoding="utf-8")
    )
    assert feature_packs == {
        "version": 1,
        "install": [{"pack_slug": "appointment-booking", "config": {}}],
    }


def test_materialize_core_composition_derives_pack_from_app_block_dependency(tmp_path):
    root = tmp_path / "repo"

    materialize_core_composition(
        root,
        {
            "composition": {
                "app_block_ids": ["forms.quote_request"],
                "feature_pack_ids": [],
            },
            "runtime": {},
        },
    )

    feature_packs = json.loads(
        (root / "p2hs" / "feature-packs.json").read_text(encoding="utf-8")
    )
    assert feature_packs["install"] == [{"pack_slug": "contact-capture", "config": {}}]


def test_materialize_core_composition_projects_form_definition_into_pack_config(tmp_path):
    root = tmp_path / "repo"
    materialize_core_composition(
        root,
        {
            "composition": {
                "app_block_ids": ["forms.quote_request"],
                "feature_pack_ids": ["contact-capture"],
                "form_definitions": {
                    "quote_request": {
                        "key": "quote_request",
                        "fields": [
                            {"key": "name", "type": "text", "required": True},
                            {"key": "phone", "type": "phone"},
                        ],
                    }
                },
            },
            "runtime": {},
        },
    )
    feature_packs = json.loads(
        (root / "p2hs" / "feature-packs.json").read_text(encoding="utf-8")
    )
    fields = feature_packs["install"][0]["config"]["form_definitions"]["quote_request"]["fields"]
    assert fields[1]["key"] == "phone"
