#!/usr/bin/env sh

set -eu

log() {
  printf '[installapp] %s\n' "$1"
}

fail() {
  printf '[installapp] %s\n' "$1" >&2
  exit 1
}

usage() {
  cat <<EOF
Usage: installapp-mise.sh [codexcli|claude-code|opencode|kimi|reasonix]

不传参数时会打开交互菜单。
EOF
}

has_command() {
  command -v "$1" >/dev/null 2>&1
}

run_install() {
  log "正在执行：$*"
  "$@"
}

require_linux() {
  os_name=$(uname -s 2>/dev/null || printf unknown)
  [ "$os_name" = "Linux" ] || fail "此脚本仅支持 Linux。当前检测到：$os_name"
}

find_mise() {
  if [ -r /etc/openwrt_release ] && has_command mise-istore; then
    command -v mise-istore
    return 0
  fi

  if has_command mise; then
    command -v mise
    return 0
  fi

  for candidate in \
    "${HOME}/.local/bin/mise" \
    "${HOME}/.local/share/mise/bin/mise" \
    "${HOME}/.mise/bin/mise"; do
    if [ -x "$candidate" ]; then
      printf '%s\n' "$candidate"
      return 0
    fi
  done

  return 1
}

http_get_quiet() {
  url=$1
  if has_command wget; then
    wget -q -T 3 -O /dev/null "$url" >/dev/null 2>&1
    return $?
  fi
  if has_command curl; then
    curl -fsS --max-time 3 -o /dev/null "$url" >/dev/null 2>&1
    return $?
  fi
  return 1
}

configure_istoreenhance_mise_accel() {
  [ -r /etc/openwrt_release ] || return 0
  has_command iStoreEnhance || has_command kspeeder || return 0

  tls_port=${KSPEEDER_PORT:-5443}
  download_gateway_available=0
  if http_get_quiet 'http://127.0.0.1:5003/api/download-gateway/routes'; then
    download_gateway_available=1
  fi

  mirror_url=${ISTOREENHANCE_MISE_NODE_UNOFFICIAL_MIRROR_URL:-https://dl-node-unofficial.linkease.net:${tls_port}/}
  if http_get_quiet "${mirror_url}index.json"; then
    export MISE_NODE_MIRROR_URL="$mirror_url"
    : "${MISE_NODE_VERIFY:=0}"
    export MISE_NODE_VERIFY
    log "Node.js 下载加速已启用：$MISE_NODE_MIRROR_URL"
  else
    log '未检测到可用的 iStoreEnhance Node.js 下载加速入口，将使用 mise 默认下载路径。'
  fi

  go_mirror_url=${ISTOREENHANCE_MISE_GO_SDK_MIRROR_URL:-https://dl-go-sdk.linkease.net:${tls_port}}
  if [ "$download_gateway_available" = "1" ]; then
    export MISE_GO_DOWNLOAD_MIRROR="$go_mirror_url"
    log "Go SDK 下载加速已启用：$MISE_GO_DOWNLOAD_MIRROR"
  else
    log '未检测到可用的 iStoreEnhance Go SDK 下载加速入口，将使用 mise 默认下载路径。'
  fi

  github_release_replacements="{\"regex:^https://github\\\\.com/(.+/.+/releases/download/.+)$\":\"https://dl-github.linkease.net:${tls_port}/\$1\"}"
  if [ -z "${MISE_URL_REPLACEMENTS:-}" ] && [ "$download_gateway_available" = "1" ]; then
    export MISE_URL_REPLACEMENTS="$github_release_replacements"
    log "GitHub Release 下载加速已启用：$MISE_URL_REPLACEMENTS"
  fi
}

ensure_mise_prerequisites() {
  log '开始检测 mise、Node.js 和 Git 前置依赖。'

  if ! mise_bin=$(find_mise); then
    fail '未找到 mise。请先按照 https://mise.jdx.dev/installing-mise.html 安装 mise。'
  fi

  version=$("$mise_bin" --version 2>/dev/null | sed -n '1p' || true)
  log "mise 已安装${version:+：$version}"
  configure_istoreenhance_mise_accel
  run_install "$mise_bin" use --global node@lts

  "$mise_bin" exec node@lts -- node --version >/dev/null 2>&1 ||
    fail 'mise 管理的 Node.js 未正确安装。'
  "$mise_bin" exec node@lts -- npm --version >/dev/null 2>&1 ||
    fail 'mise 管理的 npm 不可用。'

  has_command git || fail '未找到 Git。请先安装 Git。'
  git_version=$(git --version 2>/dev/null | sed -n '1p' || true)
  log "git 已安装${git_version:+：$git_version}"

  log 'mise、Node.js 和 Git 前置依赖检测完成，开始执行应用安装流程。'
}

normalize_choice() {
  case "$1" in
    1|codex|codexcli|codex-cli) printf 'codexcli\n' ;;
    2|claude|claude-code|claudecode) printf 'claude-code\n' ;;
    3|opencode|open-code) printf 'opencode\n' ;;
    4|kimi|kimi-code|kimicode) printf 'kimi\n' ;;
    5|reasonix) printf 'reasonix\n' ;;
    q|quit|exit) printf 'quit\n' ;;
    *) fail "未知的应用选择：$1" ;;
  esac
}

prompt_choice() {
  while :; do
    cat >&2 <<EOF

请选择要安装的Agent程序：
  1) Codex
  2) Claude Code
  3) OpenCode
  4) Kimi
  5) Reasonix
  q) quit
EOF
    printf '请输入选项：' >&2

    if choice=$(sh -c 'IFS= read -r line </dev/tty && printf "%s" "$line"' 2>/dev/null); then
      :
    elif IFS= read -r choice; then
      :
    else
      fail '未读取到菜单输入。请在交互终端运行，或传入参数：codexcli、claude-code、opencode、kimi 或 reasonix。'
    fi

    case "$choice" in
      '')
        printf '[installapp] 输入为空，请重新选择。\n' >&2
        ;;
      1|codex|codexcli|codex-cli|2|claude|claude-code|claudecode|3|opencode|open-code|4|kimi|kimi-code|kimicode|5|reasonix|q|quit|exit)
        normalize_choice "$choice"
        return 0
        ;;
      *)
        printf '[installapp] 未知的应用选择：%s，请重新输入。\n' "$choice" >&2
        ;;
    esac
  done
}

install_npm_app() {
  run_install "$mise_bin" exec node@lts -- npm "$@"
  run_install "$mise_bin" reshim
}

install_app() {
  app=$1
  log "已选择 $app，开始安装。"

  case "$app" in
    codexcli)
      install_npm_app install -g @openai/codex@0.144 --registry=https://registry.npmmirror.com
      ;;
    claude-code)
      install_npm_app install -g @anthropic-ai/claude-code --registry=https://registry.npmmirror.com
      ;;
    opencode)
      install_npm_app i -g opencode-ai --registry=https://registry.npmmirror.com
      ;;
    kimi)
      install_npm_app install -g @moonshot-ai/kimi-code --registry=https://registry.npmmirror.com
      ;;
    reasonix)
      install_npm_app i -g reasonix --registry=https://registry.npmmirror.com
      ;;
    *)
      fail "不支持的应用：$app"
      ;;
  esac

  log "$app 安装完成。"
}

run_selection() {
  selection=$1
  case "$selection" in
    codexcli|claude-code|opencode|kimi|reasonix)
      install_app "$selection"
      ;;
    quit)
      log '未选择应用，退出。'
      ;;
    *)
      fail "不支持的选择：$selection"
      ;;
  esac
}

main() {
  if [ $# -gt 1 ]; then
    usage
    exit 1
  fi
  if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
    usage
    exit 0
  fi

  if [ $# -eq 1 ]; then
    selection=$(normalize_choice "$1")
  else
    selection=$(prompt_choice)
  fi

  if [ "$selection" = "quit" ]; then
    run_selection "$selection"
    exit 0
  fi

  log "已确定安装目标：$selection。"
  require_linux
  ensure_mise_prerequisites
  run_selection "$selection"
}

main "$@"
