"""ProjectCapabilityManifest: the typed answer to "what capabilities does this
project require", and its direct feed into resolve_dependencies()."""
from __future__ import annotations

from src.domain.capabilities.dependencies import CapabilityDependency, resolve_dependencies
from src.domain.capabilities.models import ProjectCapabilityManifest, ProjectCapabilitySpec


def test_get_returns_the_matching_spec_or_none():
    manifest = ProjectCapabilityManifest(
        capabilities=(
            ProjectCapabilitySpec(key="auth", version=2),
            ProjectCapabilitySpec(key="forms", version=1, enabled=False),
        )
    )

    assert manifest.get("auth").version == 2
    assert manifest.get("forms").enabled is False
    assert manifest.get("files") is None


def test_disabled_capability_is_kept_not_omitted():
    manifest = ProjectCapabilityManifest(
        capabilities=(ProjectCapabilitySpec(key="forms", version=1, enabled=False),)
    )

    assert manifest.get("forms") is not None
    assert "forms" not in manifest.enabled_roots()


def test_enabled_roots_excludes_disabled_capabilities():
    manifest = ProjectCapabilityManifest(
        capabilities=(
            ProjectCapabilitySpec(key="auth", version=2),
            ProjectCapabilitySpec(key="forms", version=1, enabled=False),
            ProjectCapabilitySpec(key="feature_packs", version=1),
        )
    )

    assert manifest.enabled_roots() == {"auth": 2, "feature_packs": 1}


def test_manifest_feeds_resolve_dependencies_directly():
    manifest = ProjectCapabilityManifest(
        capabilities=(
            ProjectCapabilitySpec(
                key="feature_packs",
                version=1,
                dependencies=(CapabilityDependency(key="auth", minimum_version=2),),
            ),
            ProjectCapabilitySpec(key="auth", version=2),
        )
    )

    resolution = resolve_dependencies(
        roots=manifest.enabled_roots(), dependencies=manifest.dependency_map()
    )

    assert resolution.ok
    assert {r.key for r in resolution.order} == {"auth", "feature_packs"}


def test_manifest_round_trips_through_dict():
    manifest = ProjectCapabilityManifest(
        capabilities=(
            ProjectCapabilitySpec(
                key="auth",
                version=2,
                config={"audiences": ["staff", "member"]},
                dependencies=(CapabilityDependency(key="forms", required=False),),
            ),
        )
    )

    restored = ProjectCapabilityManifest.model_validate(manifest.model_dump())

    assert restored == manifest
