"""Bundled Kimi provider catalog."""
from typing import Any, Mapping
from okstra_ctl.domain.provider import (
    LeadLaunchSpec,
    ModelSpec,
    ProviderSpec,
    ServedModelAttestation,
)
from okstra_ctl.domain.role import ALL_ROLE_TOKENS
from okstra_ctl.domain.worker_exec import (
    ExecCommand,
    PolicySupport,
    WorkerExecRequest,
)
from okstra_ctl.domain.worker_presentation import JsonEvents
from okstra_ctl.domain.worker_stream import content_block_events


KIMI = {
    "kimi-k2.7-code": ModelSpec("kimi-k2.7-code", "Kimi K2.7 Code", "kimi-k2.7-code", aliases=("kimi k2.7 code",), pricing=(0.95, 0.19, 4.00)),
    "kimi-for-coding": ModelSpec("kimi-for-coding", "Kimi K2.7 Code", "kimi-for-coding"),
    "kimi-k3": ModelSpec("kimi-k3", "Kimi K3", "kimi-k3", aliases=("kimi k3",), pricing=(3.00, 0.30, 15.00)),
    "k3": ModelSpec("k3", "Kimi K3", "k3"),
    "k3-256k": ModelSpec("k3-256k", "Kimi K3 256K", "k3-256k", aliases=("kimi k3 256k",)),
}


def normalise_served_model(raw_model: str | None) -> ServedModelAttestation:
    if not raw_model or not raw_model.strip():
        return ServedModelAttestation.unknown()
    model_id = raw_model.strip().lower().removeprefix("kimi/")
    return ServedModelAttestation(
        raw_model, f"kimi/{model_id}", "exact", "provider-output"
    )


def observe_served_model(event: Mapping[str, Any]) -> str | None:
    model = event.get("model")
    if isinstance(model, str) and model.strip():
        return model
    message = event.get("message")
    if isinstance(message, Mapping):
        model = message.get("model")
        return model if isinstance(model, str) and model.strip() else None
    return None

KIMI_LEAD_LAUNCH = LeadLaunchSpec(
    executable="kimi",
    model_flag="--model",
    resume_session_id_flag="--session",
)


class KimiExecution:
    """kimi CLI invocation.

    No flag names the working directory, so the process's own is the only
    control. Returning it in the command keeps that fact inside the contract
    instead of leaving the runner to infer it.
    """

    def build_command(self, request: WorkerExecRequest) -> ExecCommand:
        cwd = request.worktree_path or request.project_root
        return ExecCommand(
            argv=(
                "kimi",
                "-p",
                request.prompt_text,
                "-m",
                request.model,
                "--output-format",
                "stream-json",
            ),
            stdin_text=None,
            cwd=cwd,
            presentation=JsonEvents(
                normalise=content_block_events,
                observe=observe_served_model,
            ),
        )

    def policy_support(self) -> PolicySupport:
        return PolicySupport(
            can_auto_approve=False,
            can_bound_write_scope=False,
            note="this CLI exposes no approval or sandbox flag",
        )


def create_provider() -> ProviderSpec:
    return ProviderSpec(
        provider="kimi",
        display_label="Kimi",
        models=KIMI,
        default_models={
            "lead": "kimi-k2.7-code",
            "analyser": "kimi-k2.7-code",
            "critic": "kimi-k3",
            "designer": "kimi-k2.7-code",
            "planner": "kimi-k2.7-code",
            "executor": "kimi-k2.7-code",
            "verifier": "kimi-k2.7-code",
            "report-writer": "kimi-k2.7-code",
            "translator": "kimi-k2.7-code",
        },
        wrapper="okstra-kimi-exec.sh",
        supported_roles=ALL_ROLE_TOKENS,
        execution_capabilities=frozenset(
            {
                "lead-session",
                "worker-artifact-io",
                "source-readonly",
                "extended-artifact-authoring",
                "project-mutation",
            }
        ),
        lead_launch=KIMI_LEAD_LAUNCH,
        exec_strategy=KimiExecution(),
        served_model_normalizer=normalise_served_model,
    )
