#!/usr/bin/env bash
# deploy/lib/common.sh — 比特骆驼自动化对冲系统 部署公共函数
# 目标系统: Ubuntu 22.04 LTS
set -e
set -u
if [ -n "${BASH_VERSION:-}" ]; then
  set -o pipefail
fi

INSTALL_ROOT="${INSTALL_ROOT:-/opt/eth_hedge_sim}"
GIT_URL="${GIT_URL:-https://git.bz121.com/dekun/eth_hedge_sim.git}"
GIT_BRANCH="${GIT_BRANCH:-main}"
BACKUP_ROOT="${BACKUP_ROOT:-/root/backups/eth_hedge_sim}"
TZ_NAME="${EHS_TZ:-Asia/Shanghai}"
NODE_MAJOR="${NODE_MAJOR:-20}"
PM2_APP_NAME="${PM2_APP_NAME:-eth-hedge-api}"
API_PORT="${API_PORT:-5155}"

LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEPLOY_DIR="$(cd "${LIB_DIR}/.." && pwd)"
REPO_ROOT="$(cd "${DEPLOY_DIR}/.." && pwd)"

log() { printf '[%s] %s\n' "$(TZ="${TZ_NAME}" date '+%Y-%m-%d %H:%M:%S')" "$*"; }
step() { echo ""; log "==> $*"; }

die() {
  echo "错误: $*" >&2
  exit 1
}

require_root() {
  if [[ "$(id -u)" -ne 0 ]]; then
    die "请使用 root 执行(推荐: sudo -i 后运行)"
  fi
}

detect_server_ip() {
  local ip=""
  if command -v hostname >/dev/null 2>&1; then
    ip="$(hostname -I 2>/dev/null | awk '{print $1}')"
  fi
  if [[ -z "${ip}" ]]; then
    ip="127.0.0.1"
  fi
  echo "${ip}"
}

# curl|bash 时 stdin 可能是管道，交互从 /dev/tty 读
cm_read() {
  local __var="$1"
  local __prompt="${2:-}"
  local __line=""
  if [[ -n "${__prompt}" ]]; then
    printf '%s' "${__prompt}" >/dev/tty 2>/dev/null || printf '%s' "${__prompt}"
  fi
  if [[ -r /dev/tty ]]; then
    IFS= read -r __line </dev/tty || true
  else
    IFS= read -r __line || true
  fi
  printf -v "${__var}" '%s' "${__line}"
}

confirm_yes() {
  local msg="$1"
  local ans=""
  cm_read ans "${msg} [y/N] "
  [[ "${ans}" == [yY] || "${ans}" == [yY][eE][sS] ]]
}

repo_ready() {
  [[ -f "${1}/deploy/manage.sh" && -f "${1}/deploy/pull_and_restart.sh" ]]
}

resolve_repo_root() {
  if repo_ready "${INSTALL_ROOT}"; then
    echo "${INSTALL_ROOT}"
    return 0
  fi
  if [[ -n "${REPO_ROOT:-}" ]] && repo_ready "${REPO_ROOT}"; then
    echo "${REPO_ROOT}"
    return 0
  fi
  return 1
}

# ---------- 运行时检测（有则跳过，无则安装） ----------

python_runtime_ok() {
  command -v python3 >/dev/null 2>&1 || return 1
  # 能创建 venv 即可；pip 在项目 .venv 内安装
  python3 -c "import venv" >/dev/null 2>&1 || return 1
  return 0
}

node_runtime_ok() {
  command -v node >/dev/null 2>&1 || return 1
  command -v npm >/dev/null 2>&1 || return 1
  return 0
}

pm2_runtime_ok() {
  command -v pm2 >/dev/null 2>&1
}

print_runtime_probe() {
  echo "环境检测:"
  if python_runtime_ok; then
    echo "  [OK] Python3 + venv       →  $(python3 --version 2>&1)"
  else
    echo "  [缺] Python3 / venv       →  将自动安装"
  fi
  if node_runtime_ok; then
    echo "  [OK] Node.js + npm         →  $(node --version 2>&1) / npm $(npm --version 2>&1)"
  else
    echo "  [缺] Node.js / npm         →  将自动安装 Node ${NODE_MAJOR}"
  fi
  if pm2_runtime_ok; then
    echo "  [OK] PM2                   →  $(pm2 -v 2>&1)"
  else
    echo "  [缺] PM2                   →  将自动安装"
  fi
}

install_python_runtime() {
  step "安装 Python3 环境 (python3 / venv / pip)"
  export DEBIAN_FRONTEND=noninteractive
  if ! command -v apt-get >/dev/null 2>&1; then
    die "非 apt 系统，请手动安装 python3 python3-venv python3-pip"
  fi
  apt-get update -qq
  apt-get install -y python3 python3-venv python3-pip
  if ! python_runtime_ok; then
    die "Python 环境安装后仍不可用，请检查 apt 源"
  fi
  log "Python 已就绪: $(python3 --version 2>&1)"
}

install_node_runtime() {
  step "安装 Node.js ${NODE_MAJOR}"
  export DEBIAN_FRONTEND=noninteractive
  if ! command -v apt-get >/dev/null 2>&1; then
    die "非 apt 系统，请手动安装 Node.js ${NODE_MAJOR}+"
  fi
  apt-get update -qq
  apt-get install -y ca-certificates curl
  curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" | bash -
  apt-get install -y nodejs
  if ! node_runtime_ok; then
    die "Node.js 安装后仍不可用"
  fi
  log "Node 已就绪: $(node --version 2>&1)"
}

install_pm2_runtime() {
  step "安装 PM2"
  if ! command -v npm >/dev/null 2>&1; then
    die "安装 PM2 需要先有 npm"
  fi
  npm install -g pm2
  if ! pm2_runtime_ok; then
    die "PM2 安装后仍不可用"
  fi
  log "PM2 已就绪: $(pm2 -v 2>&1)"
}

ensure_base_packages() {
  local need=()
  command -v git >/dev/null 2>&1 || need+=(git)
  command -v curl >/dev/null 2>&1 || need+=(curl)
  if [[ ${#need[@]} -eq 0 ]]; then
    log "基础包 git/curl 已存在，跳过"
    return 0
  fi
  if ! command -v apt-get >/dev/null 2>&1; then
    die "缺少依赖: ${need[*]}，且无 apt-get"
  fi
  step "安装基础包: ${need[*]}"
  export DEBIAN_FRONTEND=noninteractive
  apt-get update -qq
  apt-get install -y ca-certificates "${need[@]}"
}

ensure_system_deps() {
  step "环境检测 (Python / Node / PM2)"
  print_runtime_probe
  ensure_base_packages

  if python_runtime_ok; then
    log "Python 环境已存在，跳过安装"
  else
    install_python_runtime
  fi

  if node_runtime_ok; then
    log "Node.js 环境已存在，跳过安装"
  else
    install_node_runtime
  fi

  if pm2_runtime_ok; then
    log "PM2 已存在，跳过安装"
  else
    install_pm2_runtime
  fi

  step "环境确认"
  print_runtime_probe
}

pm2_stop_project() {
  if command -v pm2 >/dev/null 2>&1; then
    pm2 stop "${PM2_APP_NAME}" 2>/dev/null || true
  fi
}

pm2_delete_project() {
  if command -v pm2 >/dev/null 2>&1; then
    pm2 delete "${PM2_APP_NAME}" 2>/dev/null || true
    pm2 save 2>/dev/null || true
  fi
}

pm2_save_startup() {
  if command -v pm2 >/dev/null 2>&1; then
    pm2 save 2>/dev/null || true
    pm2 startup systemd -u root --hp /root 2>/dev/null || true
  fi
}

verify_health() {
  local port="${1:-${API_PORT}}"
  local url="http://127.0.0.1:${port}/health"
  step "健康检查 ${url}"
  local i
  for i in 1 2 3 4 5 6 7 8 9 10; do
    if curl -fsS "${url}" >/dev/null 2>&1; then
      log "health OK"
      curl -fsS "${url}" || true
      echo ""
      return 0
    fi
    sleep 1
  done
  log "警告: health 暂未就绪，请稍后检查 pm2 logs ${PM2_APP_NAME}"
  return 1
}

print_post_install_guide() {
  local ip
  ip="$(detect_server_ip)"
  echo ""
  echo "══════════════════════════════════════"
  echo " 比特骆驼自动化对冲系统 部署完成"
  echo " 目录: ${INSTALL_ROOT}"
  echo " 本机: http://${ip}:${API_PORT}/health"
  echo " 进程: pm2 status  →  ${PM2_APP_NAME}"
  echo " 管理: bash ${INSTALL_ROOT}/deploy/manage.sh"
  echo " 配置: ${INSTALL_ROOT}/.env"
  echo "══════════════════════════════════════"
  echo ""
}
