#!/usr/bin/env bash
# build_new_game_servers
#
# 自動化建置新 Zone 的 Game Servers 完整流程。
#
# 用法:
#   build_new_game_servers <TimeZone> <Region Name> <Zone ID> <MS IP> <WS IP Init> <WS ID Start> <WS ID End> [DBNAME]
#
# 範例:
#   build_new_game_servers +1 "EU (S32)" 32 10.8.73.12 10.8.73.121 3261 3299
#   build_new_game_servers +9 "JP (S10)" 10 10.150.10.1 10.150.10.11 1001 1010 MyDB

set -euo pipefail

# ── 使用說明 ──────────────────────────────────────────────────────────────────
usage() {
    cat <<EOF
用法: $(basename "$0") <TimeZone> <Region Name> <Zone ID> <MS IP> <WS IP Init> <WS ID Start> <WS ID End> [DBNAME]

  TimeZone    時區偏移，e.g. +9 / +8 / +1 / -5
  Region Name 區域顯示名稱，e.g. "EU (S32)"
  Zone ID     Zone / Set ID，e.g. 32
  MS IP       MS/GDS/GAMEDB 使用的 IP
  WS IP Init  WS IP 起始，尾數依 WS ID 計算
  WS ID Start WS ID 起始（含）
  WS ID End   WS ID 結束（含）
  DBNAME      目標 DB 名稱（預設: WebTool）

範例:
  $(basename "$0") +1 "EU (S32)" 32 10.8.73.12 10.8.73.121 3261 3299
  $(basename "$0") +9 "JP (S10)" 10 10.150.10.1 10.150.10.11 1001 1010 MyDB
EOF
    exit 1
}

[[ $# -lt 7 ]] && usage

# ── 參數 ──────────────────────────────────────────────────────────────────────
TIMEZONE="$1"
REGION_NAME="$2"
ZONE_ID="$3"
MS_IP="$4"
WS_IP_INIT="$5"
WS_ID_START="$6"
WS_ID_END="$7"
DBNAME="${8:-WebTool}"

# ── Source .gamerc（暫時關閉嚴格模式，避免 .gamerc 內部指令觸發 set -e）──────
set +euo pipefail
source "$HOME/.gamerc"
set -euo pipefail

# ── 時間戳記（JST = UTC+9）────────────────────────────────────────────────────
TIMESTAMP=$(TZ=Asia/Tokyo date +"%Y%m%dT%H%M")
OUTPUT_FILENAME="s${ZONE_ID}_db_setup_${TIMESTAMP}.txt"
LOG_FILE="/tmp/build_new_game_servers-${ZONE_ID}_${WS_ID_START}_${WS_ID_END}_${TIMESTAMP}.log"

log()       { echo "[$(date +%T)] $*"; }
log_start() { echo ""; echo "[$(date +%T)] ▶▶▶ $* 開始"; echo ""; }
log_end()   { echo ""; echo "[$(date +%T)] ◀◀◀ $* 完成"; echo ""; }

# ── 全程 stdout/stderr tee 到 log 檔 ─────────────────────────────────────────
exec > >(tee -a "$LOG_FILE") 2>&1

echo "======================================================"
echo " build_new_game_servers 開始"
echo " TimeZone:    ${TIMEZONE}"
echo " Region:      ${REGION_NAME}"
echo " Zone ID:     ${ZONE_ID}"
echo " MS IP:       ${MS_IP}"
echo " WS IP Init:  ${WS_IP_INIT}"
echo " WS ID 範圍:  ${WS_ID_START} ~ ${WS_ID_END}"
echo " DBNAME:      ${DBNAME}"
echo " Log:         ${LOG_FILE}"
echo " 時間:        $(date '+%Y-%m-%d %H:%M:%S') JST"
echo "======================================================"

# ── WS IP 計算（與 generate_hosts_n1_whole_new_zone 邏輯一致）─────────────────
calc_ws_ip() {
    local ws_ip_init="$1" ws_id="$2"
    local last_digit=$(( ws_id % 10 ))
    local offset=$(( (last_digit - 1 + 10) % 10 ))
    local prefix="${ws_ip_init%.*}"
    local last_octet="${ws_ip_init##*.}"
    echo "${prefix}.$((last_octet + offset))"
}

# 去重後收集本次所有 WS IP
collect_ws_ips() {
    declare -gA _seen=()
    WS_IPS=()
    local ws_id ip
    for ws_id in $(seq "$WS_ID_START" "$WS_ID_END"); do
        ip=$(calc_ws_ip "$WS_IP_INIT" "$ws_id")
        if [[ -z "${_seen[$ip]+_}" ]]; then
            _seen[$ip]=1
            WS_IPS+=("$ip")
        fi
    done
}

# ── Step 1: 確認 hosts 是否已有任何 WS 項目（執行前判斷）────────────────────
# Ctrl LIVEBuild（無參數）只有首次建置（hosts 完全沒有任何 WS）才使用。
# 只要 hosts 裡有任何 WS 存在（不論哪個 Zone），一律使用 nosync noreset。
log_start "Step 1: 確認 hosts WS 項目"
HOSTS_FILE="$HOME/bin/hosts"
if grep -qP "(?<!\S)WS\d" "$HOSTS_FILE" 2>/dev/null; then
    HAS_EXISTING_WS=true
    log "hosts 已有 WS 項目 → 將使用 Ctrl LIVEBuild nosync noreset"
else
    HAS_EXISTING_WS=false
    log "hosts 無任何 WS 項目 → 將使用 Ctrl LIVEBuild（首次建置）"
fi
log_end "Step 1: 確認 hosts WS 項目"

# ── Step 2: 更新 hosts ────────────────────────────────────────────────────────
log_start "Step 2: generate_hosts_n1_whole_new_zone"
"$HOME/bin/generate_hosts_n1_whole_new_zone" \
    "$REGION_NAME" "$ZONE_ID" "$MS_IP" "$WS_IP_INIT" "$WS_ID_START" "$WS_ID_END"
log_end "Step 2: generate_hosts_n1_whole_new_zone"

# ── Step 3: rewrite_etc_hosts ────────────────────────────────────────────────
log_start "Step 3: rewrite_etc_hosts"
set +u
rewrite_etc_hosts
set -u
log_end "Step 3: rewrite_etc_hosts"

# ── Step 4: rsync common（nosync noreset 模式才執行）─────────────────────────
if [[ "$HAS_EXISTING_WS" == true ]]; then
    collect_ws_ips
    log_start "Step 4: rsync common → 新機器（共 ${#WS_IPS[@]} 台）"
    for ip in "${WS_IPS[@]}"; do
        log "  rsync → $ip"
        ssh "$ip" 'cd $HOME; rsync -avz CTRL:$HOME/common .'
    done
    log_end "Step 4: rsync common"
else
    log "Step 4: 略過 rsync（首次建置）"
fi

# ── Step 5: Ctrl LIVEBuild ───────────────────────────────────────────────────
if [[ "$HAS_EXISTING_WS" == false ]]; then
    log_start "Step 5: Ctrl LIVEBuild"
    echo "yes" | "$HOME/bin/Ctrl" LIVEBuild
    log_end "Step 5: Ctrl LIVEBuild"
else
    log_start "Step 5: Ctrl LIVEBuild nosync noreset"
    echo "yes" | "$HOME/bin/Ctrl" LIVEBuild nosync noreset
    log_end "Step 5: Ctrl LIVEBuild nosync noreset"
fi

# ── Step 6: generate_dbsetup → CTRL（tee 輸出到檔案）────────────────────────
log_start "Step 6: generate_dbsetup"
ssh CTRL '$HOME/bin/generate_dbsetup '"${TIMEZONE} ${ZONE_ID} ${WS_ID_START} ${WS_ID_END} | tee /tmp/${OUTPUT_FILENAME}"
log_end "Step 6: generate_dbsetup → CTRL:/tmp/${OUTPUT_FILENAME}"

# ── Step 7: 確認 DB 是否存在，決定是否執行 psql 匯入 ─────────────────────────
log_start "Step 7: psql 匯入"
if ssh CTRL "psql -U postgres -lqt | cut -d'|' -f1 | grep -qw '${DBNAME}'"; then
    log "DB '${DBNAME}' 存在，執行 psql 匯入..."
    ssh CTRL "psql -U postgres -d ${DBNAME} < /tmp/${OUTPUT_FILENAME}"
    log_end "Step 7: psql 匯入完成"
else
    log "⚠️  DB '${DBNAME}' 不存在，已跳過 psql 匯入"
    log "    請手動執行匯入："
    log "    ssh CTRL 'psql -U postgres -d ${DBNAME} < /tmp/${OUTPUT_FILENAME}'"
    log_end "Step 7: psql 匯入（跳過）"
fi

# ── 完成 ──────────────────────────────────────────────────────────────────────
echo ""
echo "======================================================"
echo " build_new_game_servers 完成"
echo " Zone:     ${ZONE_ID}"
echo " DB:       ${DBNAME}"
echo " DB setup: CTRL:/tmp/${OUTPUT_FILENAME}"
echo " Log:      ${LOG_FILE}"
echo " 時間:     $(date '+%Y-%m-%d %H:%M:%S') JST"
echo "======================================================"
