"""Bundled Codex host strategy."""
from __future__ import annotations

import os
import shutil
from collections.abc import Callable
from pathlib import Path

from okstra_ctl.adapters.accounting import CliArtifactUsageAccountingPort
from okstra_ctl.adapters.hosts.capability_adapter import (
    INTERACTION_FUNCTIONS,
    PENDING_HOST_PORT,
    CapabilityHostAdapter,
    no_automatic_claim,
    relay_interaction_port,
)
from okstra_ctl.domain.host import HostDescriptor
from okstra_ctl.ports.host_model import NativeExecutionValueHostModelBindingPort
from okstra_ctl.registry.provider_registry import ProviderRegistry


DESCRIPTOR = HostDescriptor(
    id="codex",
    aliases=("codex",),
    native_provider_id="codex",
    required_executables=("codex",),
    launch_mode="lead",
    install_targets=frozenset({"agents"}),
    agent_id="codex",
    agent_label="Codex CLI",
    role="Codex lead",
    dispatch_mode="render-only",
    session_accounting="artifact-only",
    has_claude_session=False,
    relay_contract=str(Path(__file__).with_name("relay.md").resolve()),
)


def _okstra_home_write_checks(context) -> tuple[dict[str, object], ...]:
    if context.entry_mode != "current-session":
        return ({"id": "okstra-home-write", "status": "not-applicable"},)

    home_dir = Path(os.environ.get("OKSTRA_PROBE_HOME_DIR", str(Path.home())))
    registry_lock = home_dir / ".okstra" / "worktrees" / "registry.lock"
    try:
        registry_lock.parent.mkdir(parents=True, exist_ok=True)
        if not registry_lock.exists():
            registry_lock.touch()
        with registry_lock.open("r+"):
            pass
    except PermissionError:
        return ({
            "id": "okstra-home-write",
            "status": "required",
            "action": "switch-codex-to-full-access-and-rerun",
        },)
    return ({"id": "okstra-home-write", "status": "accepted"},)


def create_adapter(
    *,
    executable_finder: Callable[[str], str | None] = shutil.which,
    interaction_port=None,
    lead_session_port=PENDING_HOST_PORT,
    worker_dispatch_port=PENDING_HOST_PORT,
    usage_accounting_port=CliArtifactUsageAccountingPort(),
    provider_registry: ProviderRegistry | None = None,
    host_model_port=None,
) -> CapabilityHostAdapter:
    return CapabilityHostAdapter(
        DESCRIPTOR,
        executable_finder=executable_finder,
        interaction_port=(
            interaction_port
            if interaction_port is not None
            else relay_interaction_port(DESCRIPTOR.relay_contract)
        ),
        lead_session_port=lead_session_port,
        worker_dispatch_port=worker_dispatch_port,
        usage_accounting_port=usage_accounting_port,
        supported_functions=INTERACTION_FUNCTIONS,
        detector=no_automatic_claim,
        provider_registry=provider_registry,
        readiness_probe=_okstra_home_write_checks,
        host_model_port=host_model_port or NativeExecutionValueHostModelBindingPort(
            host_runtime=DESCRIPTOR.id,
            native_provider=DESCRIPTOR.native_provider_id,
        ),
    )
