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

# 一键把源码同步到开发机测试目录：Memind / memind_adm / Plaza
# 适用：更新基于源码的开发机器环境。goose 不在本流程内。

HOST="${DEPLOY_HOST:-192.168.1.9}"
USER="${DEPLOY_USER:-john}"
TARGET="${DEPLOY_USER_HOST:-${USER}@${HOST}}"

ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
EXCLUDE_FILE="${ROOT_DIR}/scripts/.rsync-exclude-test-host"

MEMIND_SRC="${MEMIND_SRC:-${ROOT_DIR}}"
ADM_SRC="${ADM_SRC:-${ROOT_DIR}/../memind_adm}"
PLAZA_SRC="${PLAZA_SRC:-${ROOT_DIR}/../tkmind_go/ui/plaza}"

MEMIND_DST="${MEMIND_DST:-/Users/john/PycharmProjects/test/test-memind}"
ADM_DST="${ADM_DST:-/Users/john/PycharmProjects/test/test-memindadm}"
PLAZA_DST="${PLAZA_DST:-/Users/john/PycharmProjects/test/test-memindplaza}"

RSYNC_OPTS=(
  -az
  --delete
  --exclude-from="${EXCLUDE_FILE}"
)

DRY_RUN=0
CHECK_ONLY=0
ONLY_MEMIND=0
ONLY_ADM=0
ONLY_PLAZA=0
SKIP_MV=0
AUTO_YES=0

usage() {
  cat <<USAGE
用法: ./scripts/deploy-to-test-host.sh [选项]

目标目录（支持环境变量覆盖）
  DEPLOY_HOST, DEPLOY_USER, DEPLOY_USER_HOST
  MEMIND_SRC, ADM_SRC, PLAZA_SRC
  MEMIND_DST, ADM_DST, PLAZA_DST
  MEMIND_STATUS_URL, ADMIN_STATUS_URL, PLAZA_URL

常用选项
  --only-memind   仅同步 test-memind
  --only-adm      仅同步 test-memindadm
  --only-plaza    仅同步 test-memindplaza
  --skip-delete   同步时不做 --delete（避免误删未排除文件）
  --dry-run       预览变更，不实际写入
  --check-only    只做连通性和目录检查，不做 rsync
  --yes           非交互，自动确认
  --help          显示帮助

示例
  ./scripts/deploy-to-test-host.sh --dry-run
  ./scripts/deploy-to-test-host.sh --only-memind --skip-delete
USAGE
}

while [[ "$#" -gt 0 ]]; do
  case "$1" in
    --only-memind) ONLY_MEMIND=1 ;;
    --only-adm) ONLY_ADM=1 ;;
    --only-plaza) ONLY_PLAZA=1 ;;
    --skip-delete) SKIP_MV=1 ;;
    --dry-run) DRY_RUN=1 ;;
    --check-only) CHECK_ONLY=1 ;;
    --yes) AUTO_YES=1 ;;
    --help|-h)
      usage
      exit 0
      ;;
    *)
      echo "未知参数: $1" >&2
      usage
      exit 1
      ;;
  esac
  shift
 done

if [[ "${ONLY_MEMIND}" -eq 1 && ("${ONLY_ADM}" -eq 1 || "${ONLY_PLAZA}" -eq 1) ]] ||
   [[ "${ONLY_ADM}" -eq 1 && "${ONLY_PLAZA}" -eq 1 ]]; then
  echo "错误: --only-* 只能选一个" >&2
  exit 1
fi

if [[ "${SKIP_MV}" -eq 1 ]]; then
  RSYNC_OPTS=(
    -az
    --exclude-from="${EXCLUDE_FILE}"
  )
fi

if [[ ! -f "${EXCLUDE_FILE}" ]]; then
  echo "错误: 未找到排除规则文件 ${EXCLUDE_FILE}" >&2
  exit 1
fi

SSH_OPTS=(-o BatchMode=yes -o ConnectTimeout=12)

log() { printf '%s\n' "$*"; }
err() { printf '%s\n' "$*" >&2; }
fail() { err "✗ $*"; exit 1; }
ok() { printf '%s\n' "✓ $*"; }

ssh_to_host() {
  ssh "${SSH_OPTS[@]}" "${TARGET}" "$*"
}

preflight_local() {
  local src=$1
  [[ -d "$src" ]] || fail "本地源目录不存在: $src"
  [[ -f "$src/.gitignore" ]] || true
  ok "本地源目录存在: $src"
}

preflight_remote() {
  local dst=$1
  local label=$2
  ssh_to_host "mkdir -p '${dst}'" >/dev/null
  if ! ssh_to_host "test -w '${dst}'" >/dev/null 2>&1; then
    fail "远端目标不可写: ${label} -> ${TARGET}:${dst}"
  fi
  ok "远端目录可写: ${label} -> ${dst}"
}

ensure_host() {
  log "检查 SSH: ${TARGET}"
  ssh_to_host "echo connected" >/dev/null || fail "SSH 连接失败：${TARGET}"
  ok "SSH 连接成功: ${TARGET}"
}

need_confirm() {
  local target=$1
  [[ "${AUTO_YES}" -eq 1 ]] && return 0
  read -r -p "确认同步 ${target}？[y/N] " input
  [[ "$input" == "y" || "$input" == "Y" ]]
}

do_sync() {
  local label=$1
  local src=$2
  local dst=$3
  local flags=("${RSYNC_OPTS[@]}")

  preflight_local "$src"
  preflight_remote "$dst" "$label"

  if [[ "${DRY_RUN}" -eq 1 ]]; then
    flags+=(--dry-run --itemize-changes)
    log "[预览] ${label}: ${src} -> ${TARGET}:${dst}"
    rsync "${flags[@]}" "${src}/" "${TARGET}:${dst}/" | head -80
    return 0
  fi

  if ! need_confirm "$label"; then
    fail "用户取消：${label}"
  fi

  log "同步中 ${label}: ${src} -> ${TARGET}:${dst}"
  rsync "${flags[@]}" "${src}/" "${TARGET}:${dst}/"
  ok "同步完成 ${label}"
}

health_check() {
  local label=$1
  local url=$2

  if [[ -z "${url}" ]]; then
    return 0
  fi

  if ssh_to_host "command -v curl >/dev/null && curl -fsS '${url}' >/dev/null" >/dev/null 2>&1; then
    ok "${label} 健康检查通过：${url}"
  else
    log "⚠ ${label} 健康检查失败：${url}（仅提示）"
  fi
}

export MEMIND_STATUS_URL="${MEMIND_STATUS_URL:-http://127.0.0.1:18081/api/status}"
export ADMIN_STATUS_URL="${ADMIN_STATUS_URL:-http://127.0.0.1:18082/healthz}"
export PLAZA_URL="${PLAZA_URL:-http://127.0.0.1:13001/plaza}"

ensure_host

if [[ "${CHECK_ONLY}" -eq 1 ]]; then
  preflight_remote "${MEMIND_DST}" "Memind"
  preflight_remote "${ADM_DST}" "memind_adm"
  preflight_remote "${PLAZA_DST}" "Plaza"
  ok "检查通过：远端目录可用"
  health_check "Memind" "${MEMIND_STATUS_URL}"
  health_check "memind_adm" "${ADMIN_STATUS_URL}"
  health_check "Plaza" "${PLAZA_URL}"
  exit 0
fi

TARGETS=()
if [[ "${ONLY_MEMIND}" -eq 1 ]]; then
  TARGETS+=("memind")
elif [[ "${ONLY_ADM}" -eq 1 ]]; then
  TARGETS+=("adm")
elif [[ "${ONLY_PLAZA}" -eq 1 ]]; then
  TARGETS+=("plaza")
else
  TARGETS+=("memind" "adm" "plaza")
fi

for t in "${TARGETS[@]}"; do
  case "$t" in
    memind)
      do_sync "Memind" "${MEMIND_SRC}" "${MEMIND_DST}"
      ;;
    adm)
      do_sync "memind_adm" "${ADM_SRC}" "${ADM_DST}"
      ;;
    plaza)
      do_sync "Plaza" "${PLAZA_SRC}" "${PLAZA_DST}"
      ;;
  esac
done

log "同步完成。建议检查："
log "  Memind:  ${MEMIND_STATUS_URL}"
log "  memind_adm: ${ADMIN_STATUS_URL}"
log "  Plaza: ${PLAZA_URL}"

echo "\n可在远端执行 restart（不包含 goose）"
echo "  ssh ${TARGET}"
echo "  cd ${MEMIND_DST} && pnpm install && pnpm dev:server 或 pm2 reload memind"
echo "  cd ${ADM_DST} && pnpm install && pnpm start:??"
echo "  cd ${PLAZA_DST} && pnpm install && pnpm dev:plaza"

echo ""
echo "如果需要，我也可以把 restart 命令固定成你们当前启动脚架构（例如 launchctl/systemd/pm2/nodemon）。"
