"""Runtime target construction + registry registration (RUN-314).

Constructs the reference backend's components and target through the
existing ``BackendRegistry`` descriptor seam. Config kwargs flow to both
the manifest factory and ``create_reference_backend_components``; the
default driver is the hermetic :class:`InProcessDriver`.
"""

from __future__ import annotations

from aces_backend_protocols.capabilities import BackendManifest
from aces_runtime.registry import BackendRegistry, RuntimeTarget, RuntimeTargetComponents

from .driver import DeploymentDriver
from .drivers.inprocess import InProcessDriver
from .evaluator import ReferenceEvaluator
from .manifest import REFERENCE_BACKEND_NAME, create_reference_backend_manifest
from .orchestrator import ReferenceOrchestrator
from .participant_runtime import ReferenceParticipantRuntime
from .provisioner import ReferenceProvisioner


def create_reference_backend_components(
    *,
    manifest: BackendManifest,
    driver: DeploymentDriver | None = None,
    **config,
) -> RuntimeTargetComponents:
    """Build the reference backend components for a manifest.

    The default ``driver`` is the hermetic in-process driver. Component
    presence matches the manifest's declared capabilities.
    """

    del config
    deployment_driver = driver if driver is not None else InProcessDriver()
    return RuntimeTargetComponents(
        provisioner=ReferenceProvisioner(deployment_driver),
        orchestrator=ReferenceOrchestrator() if manifest.has_orchestrator else None,
        evaluator=ReferenceEvaluator() if manifest.has_evaluator else None,
        participant_runtime=ReferenceParticipantRuntime() if manifest.has_participant_runtime else None,
    )


def create_reference_backend_target(**config) -> RuntimeTarget:
    """Return a fully configured reference emulation backend target."""

    manifest = create_reference_backend_manifest(**config)
    components = create_reference_backend_components(manifest=manifest, **config)
    return RuntimeTarget(
        name=REFERENCE_BACKEND_NAME,
        manifest=manifest,
        provisioner=components.provisioner,
        orchestrator=components.orchestrator,
        evaluator=components.evaluator,
        participant_runtime=components.participant_runtime,
    )


def register_reference_backend(registry: BackendRegistry) -> None:
    """Register the reference emulation backend descriptor on ``registry``."""

    registry.register(
        REFERENCE_BACKEND_NAME,
        create_reference_backend_manifest,
        create_reference_backend_components,
    )
