# retoor <retoor@molodetz.nl>

from .spec import Action, Param


def arg(
    name: str, description: str, required: bool = False, kind: str = "string"
) -> Param:
    return Param(
        name=name,
        location="body",
        description=description,
        required=required,
        type=kind,
    )


SLUG = arg("project_slug", "Project slug or uid that owns the workspace.", required=True)
CONFIRM = arg(
    "confirm",
    "Set true only after showing the exact target to the user and getting agreement.",
    kind="boolean",
)

WORKSPACE_ACTIONS: tuple[Action, ...] = (
    Action(
        name="workspace_open",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        summary=(
            "Open or resume the browser VS Code workspace for a project. "
            "Creates one if the user has none, otherwise resumes the existing one."
        ),
        params=(SLUG,),
    ),
    Action(
        name="workspace_status",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        read_only=True,
        summary=(
            "Read a workspace's state, disk and egress usage against quota, idle "
            "countdown, tunnels and any open moderation flags. The phase (stopped, "
            "starting, ready, stopping, crashed, suspended) and editor_ready come "
            "from a live probe of the editor port, so ready means the editor opens."
        ),
        params=(SLUG,),
    ),
    Action(
        name="workspace_list",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        read_only=True,
        summary="List the caller's workspaces. Administrators see every workspace.",
        params=(),
    ),
    Action(
        name="workspace_stop",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        summary="Stop a running workspace. The files and tunnels are kept.",
        params=(SLUG, CONFIRM),
    ),
    Action(
        name="workspace_delete",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        summary="Delete a workspace. Removable from admin Trash afterwards.",
        params=(SLUG, CONFIRM),
    ),
    Action(
        name="tunnel_list",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        read_only=True,
        summary="List the public HTTPS tunnels published by a workspace.",
        params=(SLUG,),
    ),
    Action(
        name="tunnel_create",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        summary=(
            "Publish a container port on a public HTTPS hostname. The resulting URL "
            "is PUBLIC and unauthenticated - warn the user before creating one."
        ),
        params=(
            SLUG,
            arg("container_port", "Port inside the container.", required=True, kind="integer"),
            arg("label", "Human label for the tunnel."),
        ),
    ),
    Action(
        name="tunnel_delete",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        summary="Remove a public tunnel. The URL stops serving immediately.",
        params=(SLUG, arg("tunnel_uid", "Tunnel uid.", required=True), CONFIRM),
    ),
    Action(
        name="workspace_quota_get",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        read_only=True,
        summary=(
            "Read the effective workspace limits for the caller, or for any user "
            "when the caller is an administrator."
        ),
        params=(arg("username", "Administrators only: whose quota to read."),),
    ),
    Action(
        name="workspace_quota_set",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        requires_admin=True,
        summary="Set a per-user workspace quota rule. Zero means inherit the global value.",
        params=(
            arg("username", "User to apply the rule to.", required=True),
            arg("max_workspaces", "Workspace count limit.", kind="integer"),
            arg("max_tunnels", "Tunnel count limit.", kind="integer"),
            arg("disk_quota_mb", "Disk quota in MB.", kind="integer"),
            arg("egress_quota_mb", "Egress quota in MB.", kind="integer"),
            arg("idle_stop_minutes", "Idle stop window in minutes.", kind="integer"),
            arg("retention_days", "Retention in days.", kind="integer"),
            arg("cpu_millicores", "CPU limit in millicores. 1000 is one core.", kind="integer"),
            arg("memory_mb", "Memory limit in MB.", kind="integer"),
        ),
    ),
    Action(
        name="workspace_editor_get",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        read_only=True,
        summary=(
            "Read the resolved DevPlace editor profile for a workspace: theme, layout, "
            "font sizes, zoom, boot terminals, how the editor opens, the container size, "
            "and where each value comes from."
        ),
        params=(
            SLUG,
            arg("username", "Administrators only. Read another member's profile."),
        ),
    ),
    Action(
        name="workspace_editor_set",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        summary=(
            "Change the caller's DevPlace editor preferences. Omitted fields are left "
            "alone; an empty string or zero means inherit the site default. Applies on "
            "the next workspace start."
        ),
        params=(
            SLUG,
            arg("theme", "devplace-dark, devplace-light or system."),
            arg("layout", "standard, terminal-focus or zen."),
            arg("panel_preset", "short, normal, tall or maximized."),
            arg("font_size", "Editor font size in pixels.", kind="integer"),
            arg("terminal_font_size", "Terminal font size in pixels.", kind="integer"),
            arg("zoom_level", "Window zoom level, -5 to 5.", kind="integer"),
            arg("boot_agent", "dpc to open the agent terminal on boot, none to skip it."),
            arg("boot_shell", "1 to open a plain shell on boot, 0 to skip it.", kind="integer"),
            arg("window_mode", "tab, window or fullscreen."),
            arg("window_width", "Editor window width in pixels.", kind="integer"),
            arg("window_height", "Editor window height in pixels.", kind="integer"),
            arg("reset", "Drop every preference and fall back to the site defaults.", kind="boolean"),
            CONFIRM,
        ),
    ),
    Action(
        name="workspace_flag_list",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        read_only=True,
        summary=(
            "List moderation flags. A member sees only flags on their own "
            "workspaces; an administrator sees every flag."
        ),
        params=(arg("status", "Filter by status: open, resolved, dismissed."),),
    ),
    Action(
        name="workspace_flag_raise",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        requires_admin=True,
        summary="Raise a moderation flag against a workspace.",
        params=(
            SLUG,
            arg("username", "Owner of the workspace.", required=True),
            arg("severity", "info, warn or critical."),
            arg("detail", "Why the flag was raised."),
        ),
    ),
    Action(
        name="workspace_flag_resolve",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        requires_admin=True,
        summary="Resolve or dismiss a moderation flag.",
        params=(
            arg("flag_uid", "Flag uid.", required=True),
            arg("status", "resolved or dismissed."),
            CONFIRM,
        ),
    ),
    Action(
        name="workspace_suspend",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        requires_admin=True,
        summary="Suspend a workspace. It stops serving; no data is destroyed.",
        params=(
            SLUG,
            arg("username", "Owner of the workspace.", required=True),
            arg("reason", "Reason shown to the owner.", required=True),
            CONFIRM,
        ),
    ),
    Action(
        name="workspace_unsuspend",
        method="LOCAL",
        path="",
        handler="workspace",
        requires_auth=True,
        requires_admin=True,
        summary="Lift a suspension and let the workspace serve again.",
        params=(SLUG, arg("username", "Owner of the workspace.", required=True)),
    ),
)
