#!/usr/bin/env bash
set -euo pipefail

APP_NAME="${CODEX_APP_NAME:-Codex}"
HOME_DIR="${HOME:?HOME is not set}"
ACTIVE_LINK="${CODEX_WORKSPACES_LINK:-$HOME_DIR/.codex}"
WORKSPACE_PREFIX="${CODEX_WORKSPACES_PREFIX:-$HOME_DIR/.codex-}"
QUIT_TIMEOUT="${CODEX_QUIT_TIMEOUT:-20}"

detect_ui_lang() {
  local forced="${CODEX_WORKSPACES_LANG:-}"
  local apple_lang=""
  local env_lang=""

  case "$forced" in
    zh|zh-*|zh_*|ZH|ZH-*|ZH_*) printf 'zh\n'; return 0 ;;
    en|en-*|en_*|EN|EN-*|EN_*) printf 'en\n'; return 0 ;;
  esac

  if command -v defaults >/dev/null 2>&1; then
    apple_lang="$(defaults read -g AppleLanguages 2>/dev/null | awk -F'"' '/"/ {print $2; exit}' || true)"
  fi

  case "$apple_lang" in
    zh|zh-*|zh_*|ZH|ZH-*|ZH_*) printf 'zh\n'; return 0 ;;
    ?*) printf 'en\n'; return 0 ;;
  esac

  env_lang="${LC_ALL:-${LC_MESSAGES:-${LANG:-}}}"
  case "$env_lang" in
    zh|zh-*|zh_*|ZH|ZH-*|ZH_*) printf 'zh\n' ;;
    *) printf 'en\n' ;;
  esac
}

UI_LANG="$(detect_ui_lang)"

is_zh() {
  [ "$UI_LANG" = "zh" ]
}

bold() {
  if [ -t 1 ]; then printf '\033[1m%s\033[0m' "$*"; else printf '%s' "$*"; fi
}

info() {
  printf '%s\n' "$*"
}

err() {
  if is_zh; then
    printf '错误: %s\n' "$*" >&2
  else
    printf 'Error: %s\n' "$*" >&2
  fi
}

die() {
  err "$*"
  exit 1
}

usage() {
  if is_zh; then
  cat <<'USAGE'
codex-workspaces - Codex 多工作区切换工具

工作区约定:
  当前工作区: ~/.codex                 软链接
  工作区目录: ~/.codex-work            工作区名 work
            ~/.codex-personal        工作区名 personal

用法:
  codex-workspaces list | ls
      查看所有工作区目录，并标出当前工作区。

  codex-workspaces current
      显示当前 ~/.codex 指向哪个工作区。

  codex-workspaces use <工作区名> [--no-stop] [--no-start] [--force]
  codex-workspaces switch <工作区名> [--no-stop] [--no-start] [--force]
  codex-workspaces <工作区名>
      关闭 Codex App -> 切换 ~/.codex 软链接 -> 启动 Codex App。
      如在 Codex 内置 Terminal 中执行，会自动转交给外部 Terminal。
      例如: codex-workspaces work
            codex-workspaces personal --no-start

  codex-workspaces stop [--force]
      关闭 Codex App。默认优雅退出；--force 会在超时后 killall。
      如在 Codex 内置 Terminal 中执行，会自动转交给外部 Terminal。

  codex-workspaces start
      启动 Codex App。
      不能在 Codex 内置 Terminal 中执行。

  codex-workspaces restart [--force]
      重启 Codex App。
      如在 Codex 内置 Terminal 中执行，会自动转交给外部 Terminal。

  codex-workspaces create <工作区名> [--migrate-current]
      创建新的工作区目录 ~/.codex-<工作区名>。
      加 --migrate-current 可将已有的真实 ~/.codex 目录迁移为该工作区。
      迁移不能在 Codex 内置 Terminal 中执行，且迁移前必须先从外部
      Terminal 关闭 Codex App。

  codex-workspaces install [目录]
      安装本脚本到 PATH 目录。默认优先选择已有 PATH 中可写的目录。

  codex-workspaces help
      显示帮助。

环境变量:
  CODEX_APP_NAME       App 名称，默认 Codex
  CODEX_QUIT_TIMEOUT   等待 App 退出秒数，默认 20
  CODEX_WORKSPACES_LINK   当前工作区链接，默认 ~/.codex
  CODEX_WORKSPACES_PREFIX 工作区目录前缀，默认 ~/.codex-
  CODEX_WORKSPACES_LANG   强制提示语言，可设为 zh 或 en
USAGE
  else
  cat <<'USAGE'
codex-workspaces - Codex multi-workspace switcher

Workspace layout:
  Active workspace: ~/.codex                 symlink
  Workspace dirs:   ~/.codex-work            workspace name: work
                  ~/.codex-personal        workspace name: personal

Usage:
  codex-workspaces list | ls
      List all workspace directories and mark the active workspace.

  codex-workspaces current
      Show where ~/.codex currently points.

  codex-workspaces use <workspace> [--no-stop] [--no-start] [--force]
  codex-workspaces switch <workspace> [--no-stop] [--no-start] [--force]
  codex-workspaces <workspace>
      Quit Codex App -> switch the ~/.codex symlink -> start Codex App.
      If run from the built-in Codex terminal, it delegates to Terminal.app.
      Examples: codex-workspaces work
                codex-workspaces personal --no-start

  codex-workspaces stop [--force]
      Quit Codex App. By default this asks the app to quit gracefully;
      --force runs killall if the app does not exit before the timeout.
      If run from the built-in Codex terminal, it delegates to Terminal.app.

  codex-workspaces start
      Start Codex App.
      Must not be run from the built-in Codex terminal.

  codex-workspaces restart [--force]
      Restart Codex App.
      If run from the built-in Codex terminal, it delegates to Terminal.app.

  codex-workspaces create <workspace> [--migrate-current]
      Create a new workspace directory ~/.codex-<workspace>.
      Add --migrate-current to migrate an existing real ~/.codex directory
      into this workspace.
      Migration must not be run from the built-in Codex terminal, and you
      must quit Codex App from an external terminal before migration.

  codex-workspaces install [directory]
      Install this script into a PATH directory. By default it chooses
      a writable directory that is already in PATH when possible.

  codex-workspaces help
      Show this help.

Environment variables:
  CODEX_APP_NAME       App name, default: Codex
  CODEX_QUIT_TIMEOUT   Seconds to wait for app exit, default: 20
  CODEX_WORKSPACES_LINK   Active workspace link, default: ~/.codex
  CODEX_WORKSPACES_PREFIX Workspace directory prefix, default: ~/.codex-
  CODEX_WORKSPACES_LANG   Force output language: zh or en
USAGE
  fi
}

strip_workspace_name() {
  local name="$1"
  name="${name##*/}"
  name="${name#.codex-}"
  printf '%s\n' "$name"
}

validate_workspace_name() {
  local name="$1"
  if [ -z "$name" ]; then
    if is_zh; then die "工作区名不能为空"; else die "Workspace name cannot be empty"; fi
  fi
  case "$name" in
    *[!A-Za-z0-9._-]*)
      if is_zh; then
        die "工作区名只能包含字母、数字、点、下划线和连字符: $name"
      else
        die "Workspace name can only contain letters, numbers, dots, underscores, and hyphens: $name"
      fi
      ;;
    .|..)
      if is_zh; then die "工作区名不能是 $name"; else die "Workspace name cannot be $name"; fi
      ;;
  esac
}

workspace_dir() {
  local name
  name="$(strip_workspace_name "$1")"
  validate_workspace_name "$name"
  printf '%s%s\n' "$WORKSPACE_PREFIX" "$name"
}

real_dir() {
  local path="$1"
  local target

  if [ -L "$path" ]; then
    target="$(readlink "$path")"
    case "$target" in
      /*) path="$target" ;;
      *) path="$(cd "$(dirname "$path")" >/dev/null 2>&1 && pwd -P)/$target" ;;
    esac
  fi

  if [ -d "$path" ]; then
    (cd "$path" >/dev/null 2>&1 && pwd -P)
  else
    printf '%s\n' "$path"
  fi
}

current_target() {
  if [ -L "$ACTIVE_LINK" ]; then
    real_dir "$ACTIVE_LINK"
  elif [ -e "$ACTIVE_LINK" ]; then
    printf 'not-a-symlink:%s\n' "$ACTIVE_LINK"
  else
    printf 'missing\n'
  fi
}

current_name() {
  local target="$1"
  local dir name dir_real

  for dir in "$WORKSPACE_PREFIX"*; do
    [ -d "$dir" ] || continue
    dir_real="$(real_dir "$dir")"
    if [ "$dir_real" = "$target" ]; then
      name="$(strip_workspace_name "$dir")"
      printf '%s\n' "$name"
      return 0
    fi
  done

  return 1
}

list_workspaces() {
  local found=0
  local target name dir dir_real marker

  target="$(current_target)"

  if is_zh; then
    printf '%s\n' "$(bold 'Codex 工作区')"
  else
    printf '%s\n' "$(bold 'Codex workspaces')"
  fi
  for dir in "$WORKSPACE_PREFIX"*; do
    [ -d "$dir" ] || continue
    found=1
    name="$(strip_workspace_name "$dir")"
    dir_real="$(real_dir "$dir")"
    marker=' '
    if [ "$dir_real" = "$target" ]; then
      marker='*'
    fi
    printf ' %s %-16s %s\n' "$marker" "$name" "$dir"
  done

  if [ "$found" -eq 0 ]; then
    if is_zh; then
      info "未找到工作区目录。可以先执行: codex-workspaces create work"
    else
      info "No workspace directories found. You can create one with: codex-workspaces create work"
    fi
  fi

  case "$target" in
    missing)
      info
      if is_zh; then
        info "当前 $ACTIVE_LINK 不存在。"
      else
        info "Current $ACTIVE_LINK does not exist."
      fi
      ;;
    not-a-symlink:*)
      info
      if is_zh; then
        info "当前 $ACTIVE_LINK 存在，但不是软链接，切换前需要手动处理。"
      else
        info "Current $ACTIVE_LINK exists, but it is not a symlink. Please handle it manually before switching."
      fi
      ;;
    *)
      if name="$(current_name "$target" 2>/dev/null)"; then
        info
        if is_zh; then
          info "当前工作区: $name -> $target"
        else
          info "Current workspace: $name -> $target"
        fi
      else
        info
        if is_zh; then
          info "当前工作区: 未匹配到工作区目录 -> $target"
        else
          info "Current workspace: no matching workspace directory -> $target"
        fi
      fi
      ;;
  esac
}

show_current() {
  local target name
  target="$(current_target)"
  case "$target" in
    missing)
      if is_zh; then die "$ACTIVE_LINK 不存在"; else die "$ACTIVE_LINK does not exist"; fi
      ;;
    not-a-symlink:*)
      if is_zh; then die "$ACTIVE_LINK 存在，但不是软链接"; else die "$ACTIVE_LINK exists, but it is not a symlink"; fi
      ;;
    *)
      if name="$(current_name "$target" 2>/dev/null)"; then
        info "$name -> $target"
      else
        info "unknown -> $target"
      fi
      ;;
  esac
}

app_running() {
  pgrep -x "$APP_NAME" >/dev/null 2>&1
}

in_codex_terminal() {
  case "${CODEX_SHELL:-}" in
    1|true|TRUE|yes|YES) return 0 ;;
  esac
  [ -n "${CODEX_THREAD_ID:-}" ] && return 0
  [ -n "${CODEX_SANDBOX:-}" ] && return 0
  [ -n "${CODEX_CI:-}" ] && return 0
  case "${CODEX_INTERNAL_ORIGINATOR_OVERRIDE:-}" in
    *Codex*|*codex*) return 0 ;;
  esac
  case "${__CFBundleIdentifier:-}" in
    com.openai.codex*) return 0 ;;
  esac
  return 1
}

shell_quote() {
  local value="$1"
  printf "'%s'" "$(printf '%s' "$value" | sed "s/'/'\\\\''/g")"
}

script_path() {
  local self="${BASH_SOURCE[0]}"
  case "$self" in
    /*) printf '%s\n' "$self" ;;
    *)
      printf '%s/%s\n' "$(cd "$(dirname "$self")" >/dev/null 2>&1 && pwd -P)" "$(basename "$self")"
      ;;
  esac
}

external_terminal_command() {
  local command=""
  local arg

  command="unset CODEX_SHELL CODEX_THREAD_ID CODEX_SANDBOX CODEX_SANDBOX_NETWORK_DISABLED CODEX_CI CODEX_INTERNAL_ORIGINATOR_OVERRIDE __CFBundleIdentifier;"
  command="$command export CODEX_APP_NAME=$(shell_quote "$APP_NAME");"
  command="$command export CODEX_QUIT_TIMEOUT=$(shell_quote "$QUIT_TIMEOUT");"
  command="$command export CODEX_WORKSPACES_LINK=$(shell_quote "$ACTIVE_LINK");"
  command="$command export CODEX_WORKSPACES_PREFIX=$(shell_quote "$WORKSPACE_PREFIX");"
  command="$command export CODEX_WORKSPACES_LANG=$(shell_quote "$UI_LANG");"
  command="$command bash $(shell_quote "$(script_path)")"
  for arg in "$@"; do
    command="$command $(shell_quote "$arg")"
  done
  printf '%s\n' "$command"
}

delegate_to_external_terminal() {
  local action="$1"
  shift
  local command
  local launcher

  command="$(external_terminal_command "$@")"

  if is_zh; then
    info "检测到 Codex 内置 Terminal，正在将${action}转交给外部 Terminal.app 执行..."
  else
    info "Detected the built-in Codex terminal; delegating $action to Terminal.app..."
  fi

  launcher="$(mktemp "${TMPDIR:-/tmp}/codex-workspaces.XXXXXX")"
  mv "$launcher" "$launcher.command"
  launcher="$launcher.command"
  {
    printf '#!/usr/bin/env bash\n'
    printf '%s\n' "$command"
    printf 'status=$?\n'
    printf 'printf "\\n[codex-workspaces] Done with exit status %%s. You can close this window.\\n" "$status"\n'
    printf 'rm -f "$0"\n'
    printf 'exit "$status"\n'
  } > "$launcher"
  chmod +x "$launcher"

  if ! open -a Terminal "$launcher" >/dev/null 2>&1; then
    rm -f "$launcher"
    if is_zh; then
      die "无法打开外部 Terminal.app。请手动打开系统 Terminal 后重新运行该命令。"
    else
      die "Could not open Terminal.app. Open the system Terminal manually and run this command again."
    fi
  fi
}

delegate_from_codex_terminal() {
  local action_zh="$1"
  local action_en="$2"
  shift 2

  if in_codex_terminal; then
    if is_zh; then
      delegate_to_external_terminal "$action_zh" "$@"
    else
      delegate_to_external_terminal "$action_en" "$@"
    fi
    exit 0
  fi
}

require_external_terminal() {
  local action="$1"
  local action_zh="$action"

  case "$action" in
    stop) action_zh="关闭 Codex" ;;
    start) action_zh="启动 Codex" ;;
    restart) action_zh="重启 Codex" ;;
    switch) action_zh="切换工作区" ;;
    migration) action_zh="迁移工作区目录" ;;
  esac

  if in_codex_terminal; then
    if is_zh; then
      die "不能在 Codex 内置 Terminal 中执行${action_zh}。请打开外部系统 Terminal，在 Codex 外部运行该命令。"
    else
      die "Cannot run $action from the built-in Codex terminal. Open an external system Terminal and run this command outside Codex."
    fi
  fi
}

ensure_app_not_running_for_migration() {
  local status

  if ! command -v pgrep >/dev/null 2>&1; then
    if is_zh; then
      die "无法检查 $APP_NAME 是否运行，因为找不到 pgrep。请先确认 $APP_NAME 已关闭。"
    else
      die "Cannot check whether $APP_NAME is running because pgrep is not available. Please confirm $APP_NAME is closed first."
    fi
  fi

  set +e
  pgrep -x "$APP_NAME" >/dev/null 2>&1
  status=$?
  set -e
  case "$status" in
    0)
      if is_zh; then
        die "$APP_NAME 正在运行。为避免配置损坏，请先从外部 Terminal 关闭 $APP_NAME 后再执行迁移。"
      else
        die "$APP_NAME is running. To avoid corrupting config files, quit $APP_NAME from an external terminal before migration."
      fi
      ;;
    1)
      return 0
      ;;
    *)
      if is_zh; then
        die "无法确认 $APP_NAME 是否运行。为避免配置损坏，请先从外部 Terminal 确认 $APP_NAME 已关闭后再执行迁移。"
      else
        die "Cannot confirm whether $APP_NAME is running. To avoid corrupting config files, confirm $APP_NAME is closed from an external terminal before migration."
      fi
      ;;
  esac
}

stop_codex() {
  local force="${1:-0}"
  local waited=0

  if [ "$force" = "1" ]; then
    delegate_from_codex_terminal "关闭 Codex" "stop Codex" stop --force
  else
    delegate_from_codex_terminal "关闭 Codex" "stop Codex" stop
  fi

  if ! app_running; then
    if is_zh; then info "$APP_NAME 未运行。"; else info "$APP_NAME is not running."; fi
    return 0
  fi

  if is_zh; then info "正在关闭 $APP_NAME ..."; else info "Quitting $APP_NAME ..."; fi
  osascript -e "tell application \"$APP_NAME\" to quit" >/dev/null 2>&1 || true

  while app_running && [ "$waited" -lt "$QUIT_TIMEOUT" ]; do
    sleep 1
    waited=$((waited + 1))
  done

  if app_running; then
    if [ "$force" = "1" ]; then
      if is_zh; then
        info "$APP_NAME 未在 ${QUIT_TIMEOUT}s 内退出，执行强制关闭。"
      else
        info "$APP_NAME did not exit within ${QUIT_TIMEOUT}s; forcing it to quit."
      fi
      killall "$APP_NAME" >/dev/null 2>&1 || true
      sleep 1
    else
      if is_zh; then
        die "$APP_NAME 未在 ${QUIT_TIMEOUT}s 内退出；可加 --force 强制关闭"
      else
        die "$APP_NAME did not exit within ${QUIT_TIMEOUT}s; add --force to force quit"
      fi
    fi
  fi

  if is_zh; then info "$APP_NAME 已关闭。"; else info "$APP_NAME has quit."; fi
}

start_codex() {
  require_external_terminal "start"
  if is_zh; then info "正在启动 $APP_NAME ..."; else info "Starting $APP_NAME ..."; fi
  open -a "$APP_NAME"
}

restart_codex() {
  local force="$1"
  if [ "$force" = "1" ]; then
    delegate_from_codex_terminal "重启 Codex" "restart Codex" restart --force
  else
    delegate_from_codex_terminal "重启 Codex" "restart Codex" restart
  fi
  stop_codex "$force"
  start_codex
}

switch_workspace() {
  local name="$1"
  shift || true

  delegate_from_codex_terminal "切换工作区" "switch workspaces" switch "$name" "$@"

  local stop_first=1
  local start_after=1
  local force=0
  local dir

  while [ "$#" -gt 0 ]; do
    case "$1" in
      --no-stop) stop_first=0 ;;
      --no-start) start_after=0 ;;
      --force|-f) force=1 ;;
      -h|--help)
        usage
        return 0
        ;;
      *)
        if is_zh; then die "未知参数: $1"; else die "Unknown option: $1"; fi
        ;;
    esac
    shift
  done

  name="$(strip_workspace_name "$name")"
  validate_workspace_name "$name"
  dir="$(workspace_dir "$name")"
  if [ ! -d "$dir" ]; then
    if is_zh; then
      die "工作区不存在: $dir。可先执行: codex-workspaces create $name"
    else
      die "Workspace does not exist: $dir. You can create it with: codex-workspaces create $name"
    fi
  fi

  if [ -e "$ACTIVE_LINK" ] && [ ! -L "$ACTIVE_LINK" ]; then
    if is_zh; then
      die "$ACTIVE_LINK 已存在但不是软链接。为避免误删，请先手动备份/迁移它。"
    else
      die "$ACTIVE_LINK already exists but is not a symlink. Please back it up or migrate it manually before switching."
    fi
  fi

  if [ "$stop_first" -eq 1 ]; then
    stop_codex "$force"
  fi

  if [ -L "$ACTIVE_LINK" ]; then
    rm "$ACTIVE_LINK"
  fi
  ln -s "$dir" "$ACTIVE_LINK"

  if is_zh; then info "已切换到: $name -> $dir"; else info "Switched to: $name -> $dir"; fi

  if [ "$start_after" -eq 1 ]; then
    start_codex
  fi
}

create_workspace() {
  local name="${1:-}"
  local dir
  local migrate_current=0

  if [ "$#" -gt 0 ]; then
    shift
  fi

  while [ "$#" -gt 0 ]; do
    case "$1" in
      --migrate-current|--migrate)
        migrate_current=1
        ;;
      -h|--help)
        usage
        return 0
        ;;
      *)
        if is_zh; then die "未知参数: $1"; else die "Unknown option: $1"; fi
        ;;
    esac
    shift
  done

  if [ -z "$name" ]; then
    if is_zh; then die "缺少工作区名，例如: codex-workspaces create work"; else die "Missing workspace name, for example: codex-workspaces create work"; fi
  fi
  name="$(strip_workspace_name "$name")"
  validate_workspace_name "$name"
  dir="$(workspace_dir "$name")"

  if [ -e "$dir" ]; then
    if is_zh; then die "工作区目录已存在: $dir"; else die "Workspace directory already exists: $dir"; fi
  fi

  if [ "$migrate_current" -eq 1 ]; then
    require_external_terminal "migration"
    ensure_app_not_running_for_migration
    if [ -L "$ACTIVE_LINK" ]; then
      if is_zh; then
        die "$ACTIVE_LINK 已经是软链接，无需迁移。"
      else
        die "$ACTIVE_LINK is already a symlink; there is nothing to migrate."
      fi
    fi
    if [ ! -e "$ACTIVE_LINK" ]; then
      if is_zh; then
        die "$ACTIVE_LINK 不存在，无法迁移。"
      else
        die "$ACTIVE_LINK does not exist, so it cannot be migrated."
      fi
    fi
    if [ ! -d "$ACTIVE_LINK" ]; then
      if is_zh; then
        die "$ACTIVE_LINK 存在但不是目录，无法迁移。"
      else
        die "$ACTIVE_LINK exists but is not a directory, so it cannot be migrated."
      fi
    fi

    mkdir -p "$(dirname "$dir")"
    mv "$ACTIVE_LINK" "$dir"
    ln -s "$dir" "$ACTIVE_LINK"
    if is_zh; then
      info "已迁移当前工作区: $ACTIVE_LINK -> $dir"
    else
      info "Migrated current workspace: $ACTIVE_LINK -> $dir"
    fi
  else
    mkdir -p "$dir"
    if is_zh; then info "已创建工作区目录: $dir"; else info "Created workspace directory: $dir"; fi
  fi
}

path_contains_dir() {
  local dir="$1"
  case ":$PATH:" in
    *":$dir:"*) return 0 ;;
    *) return 1 ;;
  esac
}

default_install_dir() {
  local dir
  for dir in "$HOME_DIR/.local/bin" "$HOME_DIR/bin" "/opt/homebrew/bin" "/usr/local/bin"; do
    if path_contains_dir "$dir" && [ -d "$dir" ] && [ -w "$dir" ]; then
      printf '%s\n' "$dir"
      return 0
    fi
  done
  for dir in "/opt/homebrew/bin" "/usr/local/bin" "$HOME_DIR/.local/bin"; do
    if path_contains_dir "$dir" || [ "$dir" = "$HOME_DIR/.local/bin" ]; then
      printf '%s\n' "$dir"
      return 0
    fi
  done
}

install_self() {
  local dest="${1:-}"
  local self="${BASH_SOURCE[0]}"

  if [ -z "$dest" ]; then
    dest="$(default_install_dir)"
  fi
  if [ -z "$dest" ]; then
    if is_zh; then
      die "无法判断安装目录，请指定，例如: codex-workspaces install /usr/local/bin"
    else
      die "Could not choose an install directory. Please specify one, for example: codex-workspaces install /usr/local/bin"
    fi
  fi

  mkdir -p "$dest"
  install -m 0755 "$self" "$dest/codex-workspaces"
  if is_zh; then info "已安装: $dest/codex-workspaces"; else info "Installed: $dest/codex-workspaces"; fi

  if ! path_contains_dir "$dest"; then
    if is_zh; then
      info "提醒: $dest 目前不在 PATH 中，需要加入 shell 配置。"
    else
      info "Note: $dest is not currently in PATH. Add it to your shell config before using the command directly."
    fi
  fi
}

main() {
  local cmd="${1:-help}"
  shift || true

  case "$cmd" in
    help|-h|--help)
      usage
      ;;
    list|ls)
      list_workspaces
      ;;
    current|whoami)
      show_current
      ;;
    use|switch|sw)
      if [ "$#" -lt 1 ]; then
        if is_zh; then die "缺少工作区名，例如: codex-workspaces use work"; else die "Missing workspace name, for example: codex-workspaces use work"; fi
      fi
      switch_workspace "$@"
      ;;
    stop|quit|close)
      local force=0
      while [ "$#" -gt 0 ]; do
        case "$1" in
          --force|-f) force=1 ;;
          *) if is_zh; then die "未知参数: $1"; else die "Unknown option: $1"; fi ;;
        esac
        shift
      done
      stop_codex "$force"
      ;;
    start|open)
      if [ "$#" -ne 0 ]; then
        if is_zh; then die "start 不需要参数"; else die "start does not take arguments"; fi
      fi
      start_codex
      ;;
    restart|reopen)
      local force=0
      while [ "$#" -gt 0 ]; do
        case "$1" in
          --force|-f) force=1 ;;
          *) if is_zh; then die "未知参数: $1"; else die "Unknown option: $1"; fi ;;
        esac
        shift
      done
      restart_codex "$force"
      ;;
    create|new)
      create_workspace "$@"
      ;;
    install)
      install_self "${1:-}"
      ;;
    *)
      if [ -d "$(workspace_dir "$cmd" 2>/dev/null || true)" ]; then
        switch_workspace "$cmd" "$@"
      else
        if is_zh; then
          err "未知命令或工作区不存在: $cmd"
        else
          err "Unknown command or workspace does not exist: $cmd"
        fi
        info
        usage
        exit 1
      fi
      ;;
  esac
}

main "$@"
