#!/usr/bin/env bash
# 請在合併後, 更新 hosts 前處理
# 目的：將 source world id 相關的 Server 目錄轉移到 prepare 目錄
# 修正：避免 world_id 子字串誤判（例如 1121 命中 11121/11211）
# 修正：不因單一 world_id/ssh/mv 失敗而中止整批，改為記錄錯誤並繼續
# 增強：打印 MOVED / INFO / ERROR log，方便 debug

set -uo pipefail

if [ $# -lt 4 ]; then
  echo "用法: $0 <environment:test/live> <dest_directory> <target_world_id> <source_world_id1> [source_world_id2 ...]" >&2
  exit 1
fi

environment="$1"; shift
dest_directory="$1"; shift
target_world_id="$1"; shift # 保留參數，但本腳本目前未使用

# 避免 ssh 卡住（需要密碼/網路 hang）
SSH_OPT=(
  -o StrictHostKeyChecking=no
  -o BatchMode=yes
  -o ConnectTimeout=10
  -o ServerAliveInterval=10
  -o ServerAliveCountMax=3
)

log_ts() {
  date '+%Y-%m-%d %H:%M:%S'
}

log_info() {
  echo "[${0##*/}] $(log_ts) INFO: $*"
}

log_moved() {
  echo "[${0##*/}] $(log_ts) MOVED: $*"
}

log_error() {
  echo "[${0##*/}] $(log_ts) ERROR: $*" >&2
}

fail_count=0

for world_id in "$@"; do
  if ! [[ "${world_id}" =~ ^[0-9]+$ ]]; then
    log_error "world_id 必須是數字：${world_id}"
    fail_count=$((fail_count + 1))
    continue
  fi

  SET_ID=$((world_id / 100))

  if [ "${environment}" == "live" ]; then
    MACHINE="WS${world_id}"
  elif [ "${environment}" == "test" ]; then
    if [ "${SET_ID}" -ge 10 ] && [ "${SET_ID}" -lt 20 ]; then
      MACHINE="MERGE_ASIA"
    elif [ "${SET_ID}" -ge 20 ] && [ "${SET_ID}" -lt 30 ]; then
      MACHINE="MERGE_US"
    elif [ "${SET_ID}" -ge 30 ] && [ "${SET_ID}" -lt 40 ]; then
      MACHINE="MERGE_EU"
    else
      log_error "Unknown SET_ID ${SET_ID} (world_id=${world_id})"
      fail_count=$((fail_count + 1))
      continue
    fi
  else
    log_error "Unknown environment ${environment}, must be test or live"
    exit 1
  fi

  log_info "START world_id=${world_id} SET_ID=${SET_ID} MACHINE=${MACHINE} DEST=\$HOME/prepare/${dest_directory}/servers${SET_ID}"

  if ! ssh "${SSH_OPT[@]}" "${MACHINE}" \
    "mkdir -p \"\$HOME/prepare/${dest_directory}/servers${SET_ID}\""; then
    log_error "mkdir failed on ${MACHINE} (world_id=${world_id}, SET_ID=${SET_ID})"
    fail_count=$((fail_count + 1))
    continue
  fi

  # 避免子字串誤判，採用數字邊界比對
  # 最後強制 exit 0，避免沒有匹配時回傳碼造成上層判定失敗
  remote_dir=$(
    ssh "${SSH_OPT[@]}" "${MACHINE}" \
      "bash -lc 'shopt -s nullglob
                cd \"\$HOME/servers${SET_ID}\" || exit 0
                for d in *; do
                  [[ -d \"\$d\" ]] || continue
                  if [[ \"\$d\" =~ (^|[^0-9])${world_id}([^0-9]|$) ]]; then
                    printf \"%s\n\" \"\$d\"
                  fi
                done
                exit 0'"
  ) || {
    log_error "list dirs failed on ${MACHINE} (world_id=${world_id}, SET_ID=${SET_ID})"
    fail_count=$((fail_count + 1))
    continue
  }

  if [ -z "${remote_dir}" ]; then
    log_info "NO_MATCH world_id=${world_id} on ${MACHINE} at \$HOME/servers${SET_ID}"
    continue
  fi

  while IFS= read -r dir; do
    [ -n "${dir}" ] || continue

    if ssh "${SSH_OPT[@]}" "${MACHINE}" \
      "cd \"\$HOME/servers${SET_ID}\" && mv \"${dir}\" \"\$HOME/prepare/${dest_directory}/servers${SET_ID}/.\""; then
      log_moved "machine=${MACHINE} world_id=${world_id} set_id=${SET_ID} dir=${dir} -> \$HOME/prepare/${dest_directory}/servers${SET_ID}/"
    else
      log_error "mv failed on ${MACHINE} (world_id=${world_id}, set_id=${SET_ID}, dir=${dir})"
      fail_count=$((fail_count + 1))
      continue
    fi
  done <<< "${remote_dir}"

  log_info "END world_id=${world_id} SET_ID=${SET_ID} MACHINE=${MACHINE}"
done

if [ "${fail_count}" -gt 0 ]; then
  log_error "DONE with errors: fail_count=${fail_count}"
  exit 2
fi

log_info "DONE OK"
exit 0

