"""Gateway-declared slash-command manifest for the relay lane (Phase 4).

The native Discord adapter registers its slash commands directly on the
Discord command tree (`_register_slash_commands`,
plugins/platforms/discord/adapter.py) — it holds the bot token. Over the
relay the CONNECTOR holds the token, so the gateway DECLARES the same
command set on its `hello` frame (`command_manifest`) and the connector
reconciles Discord's global application-command registration against it
(gateway-gateway `DiscordCommandRegistrar`: GET → diff → bulk PUT,
idempotent, best-effort).

This module is that declaration: the single source of truth for what the
relay lane advertises. It MIRRORS the native tree — same names, same
descriptions — so a user moving between a native-Discord deployment and a
hosted/relay one sees the same command palette. Interactions come back over
the passthrough plane and are normalized by
RelayAdapter._discord_interaction_to_event into the same "/name args"
COMMAND events the dispatcher already routes, so declaring a command here
requires NO new handler — the dispatcher's existing slash surface is the
handler.

Wire shape (per entry): {name, description, options?} where options rows are
Discord option objects passed through verbatim. Names must satisfy
Discord's CHAT_INPUT rules ([a-z0-9_-]{1,32}); the connector drops invalid
entries (fail-open per entry, never the whole manifest).
"""

from __future__ import annotations

from typing import Any, Dict, List

# Discord option type 3 = STRING.
_STR = 3


def _opt(name: str, description: str, *, choices: List[str] | None = None) -> Dict[str, Any]:
    row: Dict[str, Any] = {
        "type": _STR,
        "name": name,
        "description": description,
        "required": False,
    }
    if choices:
        row["choices"] = [{"name": c, "value": c} for c in choices]
    return row


def build_relay_command_manifest() -> List[Dict[str, Any]]:
    """The relay lane's Discord slash-command manifest (native-tree mirror)."""
    return [
        {"name": "new", "description": "Start a new conversation"},
        {"name": "reset", "description": "Reset your Hermes session"},
        {
            "name": "model",
            "description": "Show or change the model",
            "options": [_opt("name", "Model name. Leave empty to see current.")],
        },
        {
            "name": "reasoning",
            "description": "Show/change reasoning effort, or toggle showing it",
            "options": [
                _opt(
                    "effort",
                    "Level, reset, or show/hide. Leave empty to see current.",
                    choices=[
                        "none",
                        "minimal",
                        "low",
                        "medium",
                        "high",
                        "xhigh",
                        "max",
                        "ultra",
                        "reset",
                        "show",
                        "hide",
                    ],
                )
            ],
        },
        {
            "name": "personality",
            "description": "Set a personality",
            "options": [_opt("name", "Personality name. Leave empty to list.")],
        },
        {"name": "retry", "description": "Retry your last message"},
        {"name": "undo", "description": "Remove the last exchange"},
        {"name": "status", "description": "Show Hermes session status"},
        {"name": "sethome", "description": "Set this chat as the home channel"},
        {"name": "stop", "description": "Stop the running Hermes agent"},
        {
            "name": "steer",
            "description": "Inject a message after the next tool call (no interrupt)",
            "options": [_opt("text", "What to tell the agent")],
        },
        {"name": "compress", "description": "Compress conversation context"},
        {
            "name": "title",
            "description": "Set or show the session title",
            "options": [_opt("text", "New title. Leave empty to show.")],
        },
        {
            "name": "resume",
            "description": "Resume a previously-named session",
            "options": [_opt("name", "Session title or id")],
        },
        {"name": "usage", "description": "Show token usage for this session"},
        {"name": "help", "description": "Show available commands"},
        {"name": "insights", "description": "Show usage insights and analytics"},
        {"name": "reload-mcp", "description": "Reload MCP servers from config"},
        {
            "name": "reload-skills",
            "description": "Re-scan skills for new or removed entries",
        },
        {"name": "voice", "description": "Toggle voice reply mode"},
        {"name": "update", "description": "Update Hermes Agent to the latest version"},
        {"name": "restart", "description": "Gracefully restart the Hermes gateway"},
        {
            "name": "approve",
            "description": "Approve a pending dangerous command",
            "options": [
                _opt("scope", "Approval scope", choices=["once", "session", "always", "all"])
            ],
        },
        {
            "name": "deny",
            "description": "Deny a pending dangerous command",
            "options": [_opt("reason", "Why (relayed to the agent)")],
        },
        {
            "name": "thread",
            "description": "Create a new thread and start a Hermes session in it",
            "options": [_opt("name", "Thread name")],
        },
        {
            "name": "queue",
            "description": "Queue a prompt for the next turn (doesn't interrupt)",
            "options": [_opt("text", "The prompt to queue")],
        },
        {
            "name": "background",
            "description": "Run a prompt in the background",
            "options": [_opt("text", "The prompt to run")],
        },
    ]
