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

set -uo pipefail

# 檢查至少要有 4 個參數：
# No.1: 環境 ( test / live )
# No.2: 移動的目錄位置
# No.3: target world_id
# No.4: source world_ids

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 # 保留參數，但本腳本目前未使用
source_world_ids_str="$*"

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

fail_count=0

for world_id in "$@"; do
  # 基本檢查：world_id 必須是數字
  if ! [[ "${world_id}" =~ ^[0-9]+$ ]]; then
    echo "ERROR: world_id 必須是數字：${world_id}" >&2
    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
      echo "ERROR: Unknown SET_ID ${SET_ID} (world_id=${world_id})" >&2
      fail_count=$((fail_count + 1))
      continue
    fi
  else
    echo "ERROR: Unknown environment ${environment}, must be test or live" >&2
    exit 1
  fi

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

  # 修正 1：避免子字串誤判，採用數字邊界比對
  # 修正 2：遠端最後強制 exit 0，避免「最後一次不匹配」導致 ssh 回傳 1
  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'"
  ) || {
    echo "ERROR: list dirs failed on ${MACHINE} (world_id=${world_id}, SET_ID=${SET_ID})" >&2
    fail_count=$((fail_count + 1))
    continue
  }

  # 沒有任何匹配就跳過（不算失敗）
  if [ -z "${remote_dir}" ]; then
    echo "INFO: no matched dirs on ${MACHINE} for world_id=${world_id} (servers${SET_ID})"
    continue
  fi

  # 逐一移動（單一 mv 失敗不影響其他 dir / world_id）
  while IFS= read -r dir; do
    [ -n "${dir}" ] || continue
    echo "ssh ${SSH_OPT[*]} ${MACHINE} \"cd \$HOME/servers${SET_ID}; mv ${dir} \$HOME/prepare/${dest_directory}/servers${SET_ID}/.\""
    if ! ssh "${SSH_OPT[@]}" "${MACHINE}" \
      "cd \"\$HOME/servers${SET_ID}\" && mv \"${dir}\" \"\$HOME/prepare/${dest_directory}/servers${SET_ID}/.\""; then
      echo "ERROR: mv failed on ${MACHINE} (world_id=${world_id}, dir=${dir})" >&2
      fail_count=$((fail_count + 1))
      # 繼續移動同一個 world_id 的其他 dir
      continue
    fi
  done <<< "${remote_dir}"

done

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

echo "DONE OK"
exit 0

