from collections.abc import Iterable

from app.agents.registry.models import (
    AgentManifest,
    CapabilityManifest,
    SpecialistTemplateManifest,
    SubCommanderManifest,
)


def _validate_unique_ids(values: Iterable[str], label: str) -> set[str]:
    unique_values: set[str] = set()
    for value in values:
        if value in unique_values:
            raise ValueError(f"duplicate {label}: {value}")
        unique_values.add(value)
    return unique_values


def validate_registry_bundle(
    *,
    agents: list[AgentManifest],
    sub_commanders: list[SubCommanderManifest],
    capabilities: list[CapabilityManifest],
    specialist_templates: list[SpecialistTemplateManifest],
) -> None:
    agent_ids = _validate_unique_ids((agent.agent_id for agent in agents), "agent id")
    _validate_unique_ids(
        (sub_commander.sub_commander_id for sub_commander in sub_commanders),
        "sub commander id",
    )
    capability_ids = _validate_unique_ids(
        (capability.capability_id for capability in capabilities),
        "capability id",
    )
    _validate_unique_ids(
        (specialist_template.template_id for specialist_template in specialist_templates),
        "template id",
    )

    for sub_commander in sub_commanders:
        if sub_commander.parent_agent_id not in agent_ids:
            raise ValueError(f"unknown parent agent id: {sub_commander.parent_agent_id}")

        for capability_id in sub_commander.capability_ids:
            if capability_id not in capability_ids:
                raise ValueError(f"unknown capability id: {capability_id}")

    for specialist_template in specialist_templates:
        if specialist_template.allowed_capability_ids is None:
            continue

        for capability_id in specialist_template.allowed_capability_ids:
            if capability_id not in capability_ids:
                raise ValueError(f"unknown capability id: {capability_id}")
