#!/bin/bash
# ============================================================
#  sync-upload.sh —— 本地目录同步到服务器（全量覆盖）
#
#  只需要改下面「配置区」的 5 个变量，然后双击/命令行运行即可。
#
#  用法：
#    Git Bash 终端：  bash sync-upload.sh
#    或（Windows 资源管理器里双击 .bat 也会自动调起，见 sync-upload.bat）
#
#  原理（为什么这样做）：
#    - scp 直接传目录会在服务器多套一层、不支持排除、且不删服务器端多余文件；
#    - 本脚本用 tar 本地打包（支持 --exclude 排除）→ scp 传单个 tar 包 →
#      服务器端解压到临时目录 → mv 原子替换目标目录，实现真正的“本地覆盖服务器”。
# ============================================================

set -e

# ============================================================
# 配置区 —— 只需要填这里
# ============================================================

HOST="120.77.213.195"               # 例：192.168.1.10 或 myserver.com
PORT="22"                               # SSH 端口，默认 22
USER="root"                             # 登录用户名

LOCAL_DIR="/d/work/other/work-buddy/homeWork"   # 本地目录（绝对路径，Windows 盘符用 /d/xxx 格式）
REMOTE_DIR="/www/wwwroot/default/tx/homeWork"                 # 服务器目标目录（绝对路径）

# 需要排除的目录/文件（相对本地目录），留空则不排除
EXCLUDES=(
  ".git"
  "node_modules"
  "__pycache__"
  "*.pyc"
  ".workbuddy"
  ".gitignore"
)

# ============================================================
# 脚本逻辑（一般无需改动）
# ============================================================

GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'

echo -e "${GREEN}===== 目录同步（本地 → 服务器，全量覆盖）=====${NC}"

# 校验配置
if [[ "$HOST" == *"你的服务器"* ]]; then
  echo -e "${RED}[错误] 请先编辑脚本，填写 HOST / USER / LOCAL_DIR / REMOTE_DIR${NC}"
  exit 1
fi
if [[ ! -d "$LOCAL_DIR" ]]; then
  echo -e "${RED}[错误] 本地目录不存在: $LOCAL_DIR${NC}"
  exit 1
fi

# 组装 tar 的排除参数（tar 支持 --exclude，语义与 rsync 一致）
TAR_EXCL_ARGS=()
for e in "${EXCLUDES[@]}"; do
  [[ -n "$e" ]] && TAR_EXCL_ARGS+=(--exclude "$e")
done

# SSH 基础参数（免密登录，无需连接复用——Windows 下 ControlMaster 易触发
# "read from master failed" 报错，直接每次独立连接反而更稳定）
SSH_COMMON=(-p "$PORT" -o ConnectTimeout=15)

# 服务器上的临时目录（放在目标目录同级的隐藏目录，保证同一文件系统，mv 才能原子）
TMP_DIR="${REMOTE_DIR}.tmp_$$"

echo -e "本地目录 : ${YELLOW}$LOCAL_DIR${NC}"
echo -e "目标     : ${YELLOW}${USER}@${HOST}:${REMOTE_DIR}${NC}  (端口 $PORT)"
echo -e "排除     : ${EXCLUDES[*]:-无}"
echo ""

# 先建立 SSH 连接（已配置免密，直接连；复用连接加速后续步骤），顺便确认目录存在
echo -e "${YELLOW}[1/3] 连接服务器（免密登录）...${NC}"
ssh "${SSH_COMMON[@]}" "${USER}@${HOST}" "echo '连接成功，远端用户: \$(whoami)'"
echo ""

# 确认
read -r -p "确认将 [$LOCAL_DIR] 全量覆盖到服务器 [$REMOTE_DIR] ? (y/n): " ans
if [[ "$ans" != "y" && "$ans" != "Y" ]]; then
  echo "已取消。"
  exit 0
fi

# 上传到临时目录
echo -e "${YELLOW}[2/3] 打包并上传文件...${NC}"
# 1) 本地 tar 打包（支持 --exclude 排除），打包成单个 .tar.gz
TAR_NAME="sync_$$.tar.gz"
TAR_LOCAL="/tmp/${TAR_NAME}"
tar -czf "$TAR_LOCAL" "${TAR_EXCL_ARGS[@]}" -C "$LOCAL_DIR" .
# 2) scp 上传单个压缩包（先传到服务器 /tmp）
scp -P "$PORT" -o ConnectTimeout=15 "$TAR_LOCAL" "${USER}@${HOST}:/tmp/${TAR_NAME}"
# 3) 本地清理临时包
rm -f "$TAR_LOCAL"
# 4) 服务器端解压到临时目录
ssh "${SSH_COMMON[@]}" "${USER}@${HOST}" "
  mkdir -p '$TMP_DIR' &&
  tar -xzf /tmp/${TAR_NAME} -C '$TMP_DIR' &&
  rm -f /tmp/${TAR_NAME} &&
  echo '解压完成'
"

# 服务器端原子替换：备份旧的，把临时目录换成正式目录
echo -e "${YELLOW}[3/3] 服务器端替换目录...${NC}"
ssh "${SSH_COMMON[@]}" "${USER}@${HOST}" "
  if [ -e '$REMOTE_DIR' ]; then
    rm -rf '${REMOTE_DIR}.bak_$$'
    mv '$REMOTE_DIR' '${REMOTE_DIR}.bak_$$'
  fi
  mv '$TMP_DIR' '$REMOTE_DIR' && echo '替换完成，旧目录已备份为 ${REMOTE_DIR}.bak_$$'
"

echo ""
echo -e "${GREEN}===== 同步完成 =====${NC}"
echo -e "服务器目录: ${YELLOW}${USER}@${HOST}:${REMOTE_DIR}${NC}"
echo -e "旧版本备份: ${REMOTE_DIR}.bak_$$（确认无误后可手动删除）"
