"""Worker-dispatch boundary exposed by a host adapter."""
from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path
from typing import Literal, Protocol

from okstra_ctl.domain.worker_exec import WorkerWriteCapability


@dataclass(frozen=True)
class WorkerDispatchRequest:
    project_root: Path
    run_manifest: Path
    workspace_root: Path | None = None
    okstra_bin: Path | None = None
    requested_workers: tuple[str, ...] = ()
    # 기본은 "정하지 않음" 이다. 그래야 엔트리포인트가 역할의 예산을 쓴다.
    idle_timeout_seconds: int | None = None
    dispatch_kind: str = "initial"
    jobs_file: Path | None = None


@dataclass(frozen=True)
class WorkerDispatchPlan:
    mode: Literal["native-team", "cli-wrapper", "cmux-pane"]
    request: WorkerDispatchRequest
    backend_plan: object | None = None
    adapter_name: str | None = None
    dispatch_mode: str | None = None
    relay_contract: str | None = None
    # 워커 디스패치를 넘겨받은 어댑터가 호스트의 선언을 덮어쓸 때만 채운다.
    # `None` 은 "이 어댑터는 배송 방식에 관해 할 말이 없다" 는 뜻이고, 그
    # 자리에서는 호스트 descriptor 의 선언이 그대로 간다.
    initial_prompt_delivery_mode: str | None = None


class WorkerDispatchPort(Protocol):
    def build_plan(self, request: WorkerDispatchRequest) -> WorkerDispatchPlan: ...

    def worker_write_capability(self) -> WorkerWriteCapability: ...
