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

########################################
# merge_rollback_partial_worlds (PostgreSQL)
#
# 參數:
#   $1: merge_setup.ini 路徑 (REMOTE_MERGE_INI_FIRST_GLOBAL)
#
# 行為:
#   - source $HOME/bin/load_merge_db_setup
#   - load_merge_db_setup <merge_setup.ini>
#   - 取得 AccountDB 連線資訊
#   - 依 world_order 由上而下取得所有 WorldID
#     * 第一個視為 target_world_id，忽略
#     * 其餘視為 source_world_ids，轉成逗點分隔字串 source_world_ids_str
#
# 1) 從 _Pre AccountDB 的 worlds 還原 source ids 資料回當下 AccountDB
#    作法：pg_dump (backup) -> 匯入 (current)，為避免 PK 衝突，先 DELETE 再匯入
# 2) 刪除當下 AccountDB.fake_worlds 對應資料
#
# 備註:
#   - backup DB 名稱：預設推導為 "${AccountDBName}_${FILE_NAME}_Pre"
#   - 若無法從 ini 路徑推導 FILE_NAME，則在 pg_database 中挑選符合 "${AccountDBName}_%_Pre" 的字典序最大者
########################################

if [ "$#" -ne 1 ]; then
  echo "Usage: $0 <merge_setup.ini>" >&2
  exit 1
fi

INI_PATH="$1"
if [ ! -f "$INI_PATH" ]; then
  echo "Error: merge_setup.ini not found: $INI_PATH" >&2
  exit 1
fi
if [ ! -s "$INI_PATH" ]; then
  echo "Error: merge_setup.ini is empty: $INI_PATH" >&2
  exit 1
fi

# 必須存在 loader
LOADER="$HOME/bin/load_merge_db_setup"
if [ ! -f "$LOADER" ]; then
  echo "Error: loader not found: $LOADER" >&2
  exit 1
fi

# shellcheck source=/dev/null
source "$LOADER"

if ! declare -F load_merge_db_setup >/dev/null 2>&1; then
  echo "Error: function load_merge_db_setup not found after sourcing $LOADER" >&2
  exit 1
fi

if ! declare -F get_accountdb_value >/dev/null 2>&1; then
  echo "Error: function get_accountdb_value not found after sourcing $LOADER" >&2
  exit 1
fi

if ! declare -F join_by_comma >/dev/null 2>&1; then
  echo "Error: function join_by_comma not found after sourcing $LOADER" >&2
  exit 1
fi

# 讀取 ini
load_merge_db_setup "$INI_PATH"

# AccountDB 連線資訊
ACCOUNT_HOST="$(get_accountdb_value "AccountDBIP")"
ACCOUNT_DB="$(get_accountdb_value "AccountDBName")"
ACCOUNT_USER="$(get_accountdb_value "AccountDBUser")"
ACCOUNT_PASS="$(get_accountdb_value "AccountDBPW")"
ACCOUNT_PORT="$(get_accountdb_value "AccountDBPort")"
ACCOUNT_PORT="${ACCOUNT_PORT:-5432}"

if [ -z "$ACCOUNT_HOST" ] || [ -z "$ACCOUNT_DB" ] || [ -z "$ACCOUNT_USER" ]; then
  echo "Error: AccountDB connection info missing from $INI_PATH" >&2
  echo "  host='$ACCOUNT_HOST' db='$ACCOUNT_DB' user='$ACCOUNT_USER' port='$ACCOUNT_PORT'" >&2
  exit 1
fi

# world_order 由上而下順序（你 loader 已保證順序）
if [ "${#world_order[@]}" -lt 2 ]; then
  echo "Error: need at least 2 WorldID entries in merge_setup.ini." >&2
  echo "  world_order count: ${#world_order[@]}" >&2
  exit 1
fi

target_world_id="${world_order[0]}"
source_world_ids=( "${world_order[@]:1}" )

# 去重但保序（保險）
declare -A SEEN=()
declare -a source_world_ids_uniq=()
for wid in "${source_world_ids[@]}"; do
  if [[ -z "${SEEN[$wid]+x}" ]]; then
    SEEN["$wid"]=1
    source_world_ids_uniq+=( "$wid" )
  fi
done

if [ "${#source_world_ids_uniq[@]}" -eq 0 ]; then
  echo "No source world ids after ignoring target_world_id=${target_world_id}. Nothing to do."
  exit 0
fi

source_world_ids_str="$(join_by_comma "${source_world_ids_uniq[@]}")"

# 從路徑推導 FILE_NAME（用於推導 backup db）
FILE_NAME=""
if [[ "$INI_PATH" =~ /merge_[^/]+_(.+)_(test|live)/ ]]; then
  FILE_NAME="${BASH_REMATCH[1]}"
fi

# backup db 名稱
BACKUP_DB=""
if [ -n "$FILE_NAME" ]; then
  BACKUP_DB="${ACCOUNT_DB}_${FILE_NAME}_Pre"
else
  export PGHOST="$ACCOUNT_HOST"
  export PGPORT="$ACCOUNT_PORT"
  export PGUSER="$ACCOUNT_USER"
  export PGPASSWORD="${ACCOUNT_PASS:-}"

  BACKUP_DB="$(psql -d postgres -Atqc \
    "SELECT datname
     FROM pg_database
     WHERE datname LIKE '${ACCOUNT_DB}\_%\_Pre' ESCAPE '\\'
     ORDER BY datname DESC
     LIMIT 1;" 2>/dev/null || true)"
fi

if [ -z "$BACKUP_DB" ]; then
  echo "Error: cannot determine backup AccountDB name (_Pre)." >&2
  exit 1
fi

# 準備暫存 SQL
tmp_sql="$(mktemp /tmp/worlds_restore.XXXXXX.sql)"
cleanup() { rm -f "$tmp_sql"; }
trap cleanup EXIT

export PGHOST="$ACCOUNT_HOST"
export PGPORT="$ACCOUNT_PORT"
export PGUSER="$ACCOUNT_USER"
export PGPASSWORD="${ACCOUNT_PASS:-}"

echo "== merge_rollback_partial_worlds (PostgreSQL) =="
echo "INI              : $INI_PATH"
echo "AccountDB Host   : $ACCOUNT_HOST:$ACCOUNT_PORT"
echo "AccountDB Name   : $ACCOUNT_DB"
echo "Backup Pre DB    : $BACKUP_DB"
echo "target_world_id  : $target_world_id (ignored)"
echo "source_world_ids : $source_world_ids_str"
echo

# 1) 從 backup (_Pre) dump 出 worlds 指定 ids 的資料
pg_dump \
  --data-only \
  --inserts \
  --column-inserts \
  --table=worlds \
  --where="id IN (${source_world_ids_str})" \
  -d "$BACKUP_DB" > "$tmp_sql"

if [ ! -s "$tmp_sql" ]; then
  echo "Error: pg_dump produced empty output. Check DB '$BACKUP_DB' table 'worlds' and ids." >&2
  exit 1
fi

# 2) 套用到 current AccountDB：先刪再匯入；再刪 fake_worlds
psql -d "$ACCOUNT_DB" -v ON_ERROR_STOP=1 <<SQL
BEGIN;

-- 1) 從 _Pre AccountDB 還原 worlds（避免 PK 衝突，先刪除現況）
DELETE FROM worlds WHERE id IN (${source_world_ids_str});
\i '${tmp_sql}'

-- 2) 刪除當下 AccountDB.fake_worlds 對應資料
DELETE FROM fake_worlds WHERE id IN (${source_world_ids_str});

COMMIT;
SQL

echo "Rollback done."


