#!/bin/bash
# ivox CLI entry script.
# Provides setup/status/speak/update/voice management commands for local iVox daemon.
set -euo pipefail

resolve_script_dir() {
  local target="$1"
  if [ -L "$target" ]; then
    local link
    link="$(readlink "$target")"
    if [[ "$link" != /* ]]; then
      target="$(cd "$(dirname "$target")" && pwd)/$link"
    else
      target="$link"
    fi
  fi
  cd "$(dirname "$target")" && pwd
}

SCRIPT_DIR="$(resolve_script_dir "$0")"
ROOT_CANDIDATE="$(cd "$SCRIPT_DIR/.." && pwd)"
if [[ -n "${IVOX_ROOT:-}" && -f "${IVOX_ROOT}/package.json" ]]; then
  ROOT="$IVOX_ROOT"
elif [[ -f "$ROOT_CANDIDATE/package.json" ]]; then
  ROOT="$ROOT_CANDIDATE"
elif [[ -f "$HOME/.local/share/ivox/package.json" ]]; then
  ROOT="$HOME/.local/share/ivox"
else
  ROOT="$ROOT_CANDIDATE"
fi

VERSION="$("$ROOT/scripts/read-version.sh" 2>/dev/null || true)"
VERSION="${VERSION:-0.1.0}"
BIN_DIR="$HOME/.local/bin"
SHARE_DIR="$HOME/.local/share/ivox"
CONFIG_DIR="$HOME/.config/ivox"
SOCK="$CONFIG_DIR/ivox.sock"
PLIST="$HOME/Library/LaunchAgents/com.user.ivox.plist"
BINARY_PATH="$BIN_DIR/ivoxd"

ivox_python() {
  if [[ -n "${IVOX_PYTHON:-}" ]]; then
    echo "$IVOX_PYTHON"
  elif [[ -f "$CONFIG_DIR/py/.venv/bin/python" ]]; then
    echo "$CONFIG_DIR/py/.venv/bin/python"
  else
    echo "python3"
  fi
}

read_version() {
  "$ROOT/scripts/read-version.sh" 2>/dev/null || echo "$VERSION"
}

install_cli_runtime() {
  mkdir -p "$BIN_DIR" "$SHARE_DIR"
  if [[ "$ROOT" != "$SHARE_DIR" ]]; then
    cp "$ROOT/package.json" "$SHARE_DIR/package.json"
    rm -rf "$SHARE_DIR/scripts" "$SHARE_DIR/configs" "$SHARE_DIR/py" "$SHARE_DIR/voices"
    cp -R "$ROOT/scripts" "$SHARE_DIR/scripts"
    cp -R "$ROOT/configs" "$SHARE_DIR/configs"
    cp -R "$ROOT/py" "$SHARE_DIR/py"
    cp -R "$ROOT/voices" "$SHARE_DIR/voices"
  fi
  rm -f "$BIN_DIR/ivox"
  cp "$ROOT/scripts/ivox" "$BIN_DIR/ivox"
  chmod +x "$BIN_DIR/ivox" "$SHARE_DIR/scripts/read-version.sh" "$SHARE_DIR/scripts/ivox"
}

cmd_setup() {
  if [[ "$(uname -m)" != "arm64" ]]; then
    echo "[✗] iVox 当前仅支持 Apple Silicon (M 系列芯片)"
    exit 1
  fi

  echo "== iVox Setup =="
  mkdir -p "$CONFIG_DIR" "$BIN_DIR" "$HOME/Library/LaunchAgents"
  install_cli_runtime

  echo "--- Python 环境 ---"
  rm -rf "$CONFIG_DIR/py"
  cp -R "$ROOT/py" "$CONFIG_DIR/py"
  local venv_python="$CONFIG_DIR/py/.venv/bin/python"
  if [[ ! -f "$venv_python" ]]; then
    "${IVOX_PYTHON:-python3}" -m venv "$CONFIG_DIR/py/.venv"
    "$venv_python" -m pip install --quiet mlx-audio==0.4.3 librosa==0.11.0 soundfile==0.13.1
  fi

  echo "--- 音色 ---"
  mkdir -p "$CONFIG_DIR/voices"
  cp -R "$ROOT/voices/." "$CONFIG_DIR/voices/"

  echo "--- 配置 ---"
  if [[ ! -f "$CONFIG_DIR/config.json" ]]; then
    cp "$ROOT/configs/config.example.json" "$CONFIG_DIR/config.json"
  fi

  echo "--- Code CLI Hooks ---"
  cp "$ROOT/configs/hook-speak.sh" "$CONFIG_DIR/hook-speak.sh"
  cp "$ROOT/configs/hook-speak.js" "$CONFIG_DIR/hook-speak.js"
  cp "$ROOT/configs/ivox.ts" "$CONFIG_DIR/ivox.ts"
  chmod +x "$CONFIG_DIR/hook-speak.sh" 2>/dev/null || true
  PYTHONPATH="$CONFIG_DIR/py" "$venv_python" -m ivox_tts.install_hooks

  echo "--- 模型 ---"
  local model_dir="$CONFIG_DIR/models/Qwen3-TTS-12Hz-1.7B-Base-8bit"
  if [[ ! -f "$model_dir/model.safetensors" ]]; then
    "$venv_python" -m pip install --quiet modelscope
    "$venv_python" -c "
from modelscope import snapshot_download
print('正在下载，请耐心等待...')
snapshot_download('mlx-community/Qwen3-TTS-12Hz-1.7B-Base-8bit', local_dir='$model_dir')
"
  fi

  echo "--- 启动服务 ---"
  sed "s|BINARY_PATH_PLACEHOLDER|$BINARY_PATH|g" "$ROOT/configs/com.user.ivox.plist" > "$PLIST"
  launchctl bootstrap "gui/$(id -u)" "$PLIST" 2>/dev/null || true
  launchctl kickstart -k "gui/$(id -u)/com.user.ivox" 2>/dev/null || true
  echo "iVox setup 完成!"
}

cmd_status() {
  echo "iVox $VERSION"
  if pgrep ivoxd >/dev/null 2>&1; then
    echo "  进程: $(pgrep ivoxd) ✓"
  else
    echo "  进程: 未运行 ✗"
  fi
  [[ -S "$SOCK" ]] && echo "  Socket: ✓" || echo "  Socket: ✗"
}

cmd_restart() {
  launchctl bootstrap "gui/$(id -u)" "$PLIST" 2>/dev/null || true
  launchctl kickstart -k "gui/$(id -u)/com.user.ivox" >/dev/null 2>&1 || true
  echo "ivox: restarted"
}

cmd_stop() {
  launchctl bootout "gui/$(id -u)/com.user.ivox" 2>/dev/null || true
  pkill -f ivoxd 2>/dev/null || true
  echo "ivox: stopped"
}

cmd_uninstall() {
  cmd_stop
  launchctl bootout "gui/$(id -u)/com.user.ivox" 2>/dev/null || true
  rm -rf "$CONFIG_DIR" "$SHARE_DIR"
  rm -f "$PLIST" "$BIN_DIR/ivoxd" "$BIN_DIR/ivox"
  echo "iVox 已卸载"
}

cmd_update() {
  echo "ivox: updating... (当前版本: $VERSION)"
  if ! command -v npm >/dev/null 2>&1; then
    echo "[✗] 未检测到 npm，无法自动更新。"
    return 1
  fi
  npm update -g @xdfnet/ivox

  if [[ -d "$ROOT/py/ivox_tts" ]]; then
    rm -rf "$CONFIG_DIR/py/ivox_tts"
    cp -R "$ROOT/py/ivox_tts" "$CONFIG_DIR/py/ivox_tts"
  fi
  if [[ -f "$ROOT/configs/hook-speak.sh" ]]; then
    cp "$ROOT/configs/hook-speak.sh" "$CONFIG_DIR/hook-speak.sh"
    cp "$ROOT/configs/hook-speak.js" "$CONFIG_DIR/hook-speak.js"
    cp "$ROOT/configs/ivox.ts" "$CONFIG_DIR/ivox.ts"
    chmod +x "$CONFIG_DIR/hook-speak.sh" 2>/dev/null || true
  fi
  if [[ -f "$CONFIG_DIR/py/.venv/bin/python" ]]; then
    "$CONFIG_DIR/py/.venv/bin/python" -m pip install --quiet --upgrade mlx-audio librosa soundfile
  fi
  install_cli_runtime
  cmd_restart
  echo "ivox: update complete → v$(read_version)"
}

cmd_logs() {
  tail -n "${1:-120}" "$CONFIG_DIR/ivox.log" 2>/dev/null || true
}

cmd_speak() {
  local source=""
  if [[ "${1:-}" == "-s" || "${1:-}" == "--source" ]]; then
    source="${2:-}"
    shift 2
  fi
  local payload="$*"
  if [[ -n "$source" && "$payload" != \{source:* ]]; then
    payload="{source:${source}}${payload}"
  fi
  if [[ "${IVOX_CLI_PRINT_PAYLOAD:-}" == "1" ]]; then
    printf "%s" "$payload"
    return 0
  fi
  printf "%s" "$payload" | nc -U -w5 "$SOCK" 2>/dev/null || echo "ivox: socket 不可用，请先运行 ivox setup 或 ivox restart" >&2
}

cmd_voice_list() {
  PYTHONPATH="$CONFIG_DIR/py" "$(ivox_python)" -m ivox_tts.worker voices --config "$CONFIG_DIR/config.json"
}

cmd_voice_clone_volcengine() {
  PYTHONPATH="$CONFIG_DIR/py" "$(ivox_python)" -m ivox_tts.clone_volcengine --config "$CONFIG_DIR/config.json" "$@"
}

case "${1:-}" in
  setup) cmd_setup ;;
  update) cmd_update ;;
  uninstall) cmd_uninstall ;;
  status) cmd_status ;;
  restart) cmd_restart ;;
  stop) cmd_stop ;;
  logs) shift; cmd_logs "${1:-120}" ;;
  speak) shift; cmd_speak "$@" ;;
  voice)
    shift
    case "${1:-}" in
      list) cmd_voice_list ;;
      clone)
        shift
        [[ "${1:-}" == "volcengine" ]] || { echo "usage: ivox voice clone volcengine ..."; exit 1; }
        shift
        cmd_voice_clone_volcengine "$@"
        ;;
      *) echo "usage: ivox voice list | ivox voice clone volcengine ..."; exit 1 ;;
    esac
    ;;
  version|-v|--version) echo "iVox $VERSION" ;;
  ""|status) cmd_status ;;
  *) cmd_speak "$@" ;;
esac
