"""Host worker-dispatch strategies and host-port decoration."""
from __future__ import annotations

from collections.abc import Mapping

from ... import dispatch_core
from ...domain.host import HostDescriptor
from ...registry.provider_registry import ProviderRegistry
from ...ports.worker_dispatch import WorkerDispatchPort
from .cli_wrapper import CliWrapperDispatchPort
from .native_team import NativeTeamDispatchPort


def provider_worker_wrappers(
    registry: ProviderRegistry,
    report_writer_provider: str = "claude",
) -> Mapping[str, str]:
    wrappers = {
        provider_id: registry.resolve(provider_id).wrapper
        for provider_id in registry.ids("analyser")
        if registry.resolve(provider_id).wrapper
    }
    report_writer = registry.resolve(report_writer_provider)
    if "report-writer" not in report_writer.supported_roles:
        raise dispatch_core.DispatchError(
            f"provider {report_writer_provider!r} does not support report-writer"
        )
    return {**wrappers, "report-writer": report_writer.wrapper}


def default_worker_dispatch_port(
    descriptor: HostDescriptor,
    provider_registry: ProviderRegistry | None = None,
) -> WorkerDispatchPort:
    if descriptor.dispatch_mode == "team":
        return NativeTeamDispatchPort()
    wrappers = (
        provider_worker_wrappers(provider_registry)
        if provider_registry is not None
        else None
    )
    return CliWrapperDispatchPort(
        supported_worker_wrappers=wrappers,
        unsupported_worker_label=f"{descriptor.id} lead",
        required_lead_runtime=descriptor.id,
        default_backend=dispatch_core.BACKEND_CLI_WRAPPER,
    )


class WorkerDispatchHostAdapter:
    def __init__(self, host_adapter, worker_dispatch_port: WorkerDispatchPort) -> None:
        self._host_adapter = host_adapter
        self._worker_dispatch_port = worker_dispatch_port
        self.descriptor = host_adapter.descriptor

    def detect(self, context):
        return self._host_adapter.detect(context)

    def probe(self, context):
        return self._host_adapter.probe(context)

    def interaction(self):
        return self._host_adapter.interaction()

    def lead_session(self):
        return self._host_adapter.lead_session()

    def worker_dispatch(self) -> WorkerDispatchPort:
        return self._worker_dispatch_port

    def usage_accounting(self):
        return self._host_adapter.usage_accounting()


def with_worker_dispatch(
    host_adapter,
    worker_dispatch_port: WorkerDispatchPort,
) -> WorkerDispatchHostAdapter:
    return WorkerDispatchHostAdapter(host_adapter, worker_dispatch_port)


__all__ = (
    "WorkerDispatchHostAdapter",
    "default_worker_dispatch_port",
    "provider_worker_wrappers",
    "with_worker_dispatch",
)
