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

########################################
# Usage / 參數檢查
########################################
if [ "$#" -ne 2 ]; then
    echo "Usage: $0 <ENVIRONMENT: test|live> <FILE_NAME>" >&2
    echo "Example: $0 test 20251209_01" >&2
    exit 1
fi

ENVIRONMENT="$1"
FILE_NAME="$2"

case "$ENVIRONMENT" in
    test|live)
        ;;
    *)
        echo "Error: ENVIRONMENT must be 'test' or 'live', got '$ENVIRONMENT'." >&2
        exit 1
        ;;
esac

INPUT_FILE="$HOME/bin/merge_n1/${ENVIRONMENT}/${FILE_NAME}"

if [ ! -f "$INPUT_FILE" ]; then
    echo "Error: input file not found: $INPUT_FILE" >&2
    exit 1
fi

if [ ! -s "$INPUT_FILE" ]; then
    echo "Error: input file is empty: $INPUT_FILE" >&2
    exit 1
fi

########################################
# 資料結構宣告
# - list_worlds[LID]  : 該 List 的 world 清單 (字串: "1101 1107 1108")
# - list_setid[LID]   : 該 List 的 SET_ID (整數)
# - set_lists[SET_ID] : 該 SET_ID 底下有哪些 LID (字串: "L1 L3 ...")
# - set_first_list[SET_ID] : 該 SET_ID 下的第一個 LID
# - all_lists         : 依檔案順序的所有 LID
########################################
declare -A list_worlds
declare -A list_setid
declare -A set_lists
declare -A set_first_list
declare -a all_lists

########################################
# 讀取檔案，建立結構 & 檢查每行 SetID 一致性
########################################
LINE_NO=0

while IFS= read -r line || [ -n "$line" ]; do
    LINE_NO=$((LINE_NO + 1))

    # 去掉前後空白
    line_trimmed="${line#"${line%%[![:space:]]*}"}"
    line_trimmed="${line_trimmed%"${line_trimmed##*[![:space:]]}"}"

    # 跳過空行或註解行
    if [ -z "$line_trimmed" ] || [[ "$line_trimmed" =~ ^# ]]; then
        continue
    fi

    # 拆成陣列 WORLDS
    read -r -a WORLDS <<< "$line_trimmed"

    if [ "${#WORLDS[@]}" -lt 1 ]; then
        echo "Error: line $LINE_NO has no WorldID: '$line'" >&2
        exit 1
    fi

    # 檢查每個 WorldID 的 SetID
    LINE_SET_ID=""
    for wid in "${WORLDS[@]}"; do
        if ! [[ "$wid" =~ ^[0-9]+$ ]]; then
            echo "Error: line $LINE_NO has non-numeric WorldID '$wid'." >&2
            exit 1
        fi

        wid_set_id=$(( wid / 100 ))
        if [ -z "$LINE_SET_ID" ]; then
            LINE_SET_ID="$wid_set_id"
        else
            if (( wid_set_id != LINE_SET_ID )); then
                echo "Error: line $LINE_NO has mixed SET_ID: expected $LINE_SET_ID, got $wid_set_id (WorldID: $wid)." >&2
                exit 1
            fi
        fi
    done

    # 建立此 List 的 ID
    LID="L${LINE_NO}"
    list_worlds["$LID"]="$line_trimmed"
    list_setid["$LID"]="$LINE_SET_ID"
    all_lists+=( "$LID" )

    # 加入 set_lists 結構
    if [[ -z "${set_lists[$LINE_SET_ID]+x}" ]]; then
        # 此 SET_ID 第一次出現
        set_lists["$LINE_SET_ID"]="$LID"
        set_first_list["$LINE_SET_ID"]="$LID"
    else
        set_lists["$LINE_SET_ID"]+=" $LID"
    fi

done < "$INPUT_FILE"

if [ "${#all_lists[@]}" -eq 0 ]; then
    echo "Error: no valid WorldID lists found in file: $INPUT_FILE" >&2
    exit 1
fi

########################################
# SHOW 結構（方便除錯，可必要時註解掉）
########################################
echo "Input file      : $INPUT_FILE"
echo "Environment     : $ENVIRONMENT"
echo "Lists by SET_ID :"
for set_id in "${!set_lists[@]}"; do
    echo "  SET_ID $set_id => ${set_lists[$set_id]}"
done
echo

########################################
# 共用變數
########################################
TODAY=$(date +"%Y%m%d")

########################################
# 工具函式：依 SET_ID 取得 AREA, MACHINE, DIRECTORY_NAME
########################################
get_area() {
    local sid="$1"
    local area=""
    if (( sid >= 10 && sid < 20 )); then
        area="asia"
    elif (( sid >= 20 && sid < 30 )); then
        area="us"
    elif (( sid >= 30 && sid < 40 )); then
        area="eu"
    else
        echo "Error: unsupported SET_ID '$sid' for AREA mapping." >&2
        return 1
    fi
    echo "$area"
}

########################################
# Step 4: 產生合併所需的目錄與檔案
#   ssh ${MACHINE} "$HOME/bin/generate_merge_preparation ${DIRECTORY_NAME} ${WORLD_ID_LISTS}"
########################################
for set_id in "${!set_lists[@]}"; do
    AREA=$(get_area "$set_id")
    DIRECTORY_NAME="merge_${AREA}_${FILE_NAME}_${ENVIRONMENT}"
    MACHINE="MS${set_id}"

    # 這個 SET_ID 底下所有 List
    read -r -a LIDS <<< "${set_lists[$set_id]}"

    echo "==== SET_ID ${set_id} / AREA=${AREA} / MACHINE=${MACHINE} ===="

    for lid in "${LIDS[@]}"; do
        WORLD_ID_LISTS="${list_worlds[$lid]}"
        echo "[generate_merge_preparation] $MACHINE $DIRECTORY_NAME :: $WORLD_ID_LISTS"
        ssh "$MACHINE" "\$HOME/bin/generate_merge_preparation ${DIRECTORY_NAME} ${WORLD_ID_LISTS}"
    done
done

########################################
# Step 5: 檢查 DB 連線
#   WORLD_ID_LISTS_STR: 1101 1107 1108 => 1101_1107_1108
#   ssh ${MACHINE} "$HOME/bin/merge_db_connect_verify \"$HOME/servers${SET_ID}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}/merge_setup.ini\""
########################################
for set_id in "${!set_lists[@]}"; do
    AREA=$(get_area "$set_id")
    DIRECTORY_NAME="merge_${AREA}_${FILE_NAME}_${ENVIRONMENT}"
    MACHINE="MS${set_id}"

    read -r -a LIDS <<< "${set_lists[$set_id]}"

    for lid in "${LIDS[@]}"; do
        WORLD_ID_LISTS="${list_worlds[$lid]}"
        WORLD_ID_LISTS_STR=${WORLD_ID_LISTS// /_}
        REMOTE_BASE_DIR="\$HOME/servers${set_id}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}"
        REMOTE_MERGE_INI="${REMOTE_BASE_DIR}/merge_setup.ini"

        echo "[merge_db_connect_verify] $MACHINE $REMOTE_MERGE_INI"
        ssh "$MACHINE" "\$HOME/bin/merge_db_connect_verify \"${REMOTE_MERGE_INI}\""
    done
done

########################################
# DB 備份前置作業 (Pre)
# a. 第一個 List    : AccountDB
# b. 每個 SetID 第一個 List : GameDB
# c. 每個 List      : WorldDB
########################################

# a. 第一個 List (global 第一個 LID) - AccountDB
FIRST_LID_GLOBAL="${all_lists[0]}"
FIRST_SETID_GLOBAL="${list_setid[$FIRST_LID_GLOBAL]}"
AREA=$(get_area "$FIRST_SETID_GLOBAL")
DIRECTORY_NAME="merge_${AREA}_${FILE_NAME}_${ENVIRONMENT}"
MACHINE="MS${FIRST_SETID_GLOBAL}"
WORLD_ID_LISTS="${list_worlds[$FIRST_LID_GLOBAL]}"
WORLD_ID_LISTS_STR=${WORLD_ID_LISTS// /_}
REMOTE_BASE_DIR="\$HOME/servers${FIRST_SETID_GLOBAL}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}"
REMOTE_MERGE_INI="${REMOTE_BASE_DIR}/merge_setup.ini"

echo "[Pre-AccountDB] First global list: $FIRST_LID_GLOBAL ($WORLD_ID_LISTS) on $MACHINE"
ssh "$MACHINE" "\$HOME/bin/merge_db_backup \"${REMOTE_MERGE_INI}\" _${TODAY}_Pre AccountDB"

# b. 每個 SetID 下的第一個 List - GameDB
for set_id in "${!set_first_list[@]}"; do
    FIRST_LID="${set_first_list[$set_id]}"
    AREA=$(get_area "$set_id")
    DIRECTORY_NAME="merge_${AREA}_${FILE_NAME}_${ENVIRONMENT}"
    MACHINE="MS${set_id}"
    WORLD_ID_LISTS="${list_worlds[$FIRST_LID]}"
    WORLD_ID_LISTS_STR=${WORLD_ID_LISTS// /_}
    REMOTE_BASE_DIR="\$HOME/servers${set_id}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}"
    REMOTE_MERGE_INI="${REMOTE_BASE_DIR}/merge_setup.ini"

    echo "[Pre-GameDB] SET_ID=${set_id} first list: $FIRST_LID ($WORLD_ID_LISTS) on $MACHINE"
    ssh "$MACHINE" "\$HOME/bin/merge_db_backup \"${REMOTE_MERGE_INI}\" _${TODAY}_Pre GameDB"
done

# c. 每個 List - WorldDB
for lid in "${all_lists[@]}"; do
    set_id="${list_setid[$lid]}"
    AREA=$(get_area "$set_id")
    DIRECTORY_NAME="merge_${AREA}_${FILE_NAME}_${ENVIRONMENT}"
    MACHINE="MS${set_id}"
    WORLD_ID_LISTS="${list_worlds[$lid]}"
    WORLD_ID_LISTS_STR=${WORLD_ID_LISTS// /_}
    REMOTE_BASE_DIR="\$HOME/servers${set_id}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}"
    REMOTE_MERGE_INI="${REMOTE_BASE_DIR}/merge_setup.ini"

    echo "[Pre-WorldDB] LID=${lid}, SET_ID=${set_id} ($WORLD_ID_LISTS) on $MACHINE"
    ssh "$MACHINE" "\$HOME/bin/merge_db_backup \"${REMOTE_MERGE_INI}\" _${TODAY}_Pre WorldDB"
done

########################################
# 執行合併作業
#   每個 List:
#   ssh ${MACHINE} "cd $HOME/servers${SET_ID}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}/; nohup ./merge_exec &"
########################################
for lid in "${all_lists[@]}"; do
    set_id="${list_setid[$lid]}"
    AREA=$(get_area "$set_id")
    DIRECTORY_NAME="merge_${AREA}_${FILE_NAME}_${ENVIRONMENT}"
    MACHINE="MS${set_id}"
    WORLD_ID_LISTS="${list_worlds[$lid]}"
    WORLD_ID_LISTS_STR=${WORLD_ID_LISTS// /_}
    REMOTE_BASE_DIR="\$HOME/servers${set_id}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}"

    echo "[merge_exec] LID=${lid}, SET_ID=${set_id} ($WORLD_ID_LISTS) on $MACHINE"
    ssh "$MACHINE" "cd ${REMOTE_BASE_DIR}; nohup ./merge_exec &"
done

########################################
# 檢查 Server log
#   每個 List:
#   ssh ${MACHINE} "cd ...; grep -E '...' Test.log*"
########################################
for lid in "${all_lists[@]}"; do
    set_id="${list_setid[$lid]}"
    AREA=$(get_area "$set_id")
    DIRECTORY_NAME="merge_${AREA}_${FILE_NAME}_${ENVIRONMENT}"
    MACHINE="MS${set_id}"
    WORLD_ID_LISTS="${list_worlds[$lid]}"
    WORLD_ID_LISTS_STR=${WORLD_ID_LISTS// /_}
    REMOTE_BASE_DIR="\$HOME/servers${set_id}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}"

    echo "[log check] LID=${lid}, SET_ID=${set_id} ($WORLD_ID_LISTS) on $MACHINE"
    ssh "$MACHINE" "cd ${REMOTE_BASE_DIR}; grep -E ',WolrdDB|,WorldDB|,GameDB|,AccountDB|,Done| autosend_info| redenvelope_info' Test.log* || echo 'No match in Test.log*'"
done

########################################
# DB 備份後置作業 (Post)
# a. 第一個 List    : AccountDB
# b. 每個 SetID 第一個 List : GameDB
# c. 每個 List      : WorldDB
########################################

# a. 第一個 List (global) - AccountDB
echo "[Post-AccountDB] First global list: $FIRST_LID_GLOBAL ($WORLD_ID_LISTS) on $MACHINE"
ssh "$MACHINE" "\$HOME/bin/merge_db_backup \"${REMOTE_MERGE_INI}\" _${TODAY}_Post AccountDB"

# b. 每個 SetID 下的第一個 List - GameDB
for set_id in "${!set_first_list[@]}"; do
    FIRST_LID="${set_first_list[$set_id]}"
    AREA=$(get_area "$set_id")
    DIRECTORY_NAME="merge_${AREA}_${FILE_NAME}_${ENVIRONMENT}"
    MACHINE="MS${set_id}"
    WORLD_ID_LISTS="${list_worlds[$FIRST_LID]}"
    WORLD_ID_LISTS_STR=${WORLD_ID_LISTS// /_}
    REMOTE_BASE_DIR="\$HOME/servers${set_id}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}"
    REMOTE_MERGE_INI="${REMOTE_BASE_DIR}/merge_setup.ini"

    echo "[Post-GameDB] SET_ID=${set_id} first list: $FIRST_LID ($WORLD_ID_LISTS) on $MACHINE"
    ssh "$MACHINE" "\$HOME/bin/merge_db_backup \"${REMOTE_MERGE_INI}\" _${TODAY}_Post GameDB"
done

# c. 每個 List - WorldDB
for lid in "${all_lists[@]}"; do
    set_id="${list_setid[$lid]}"
    AREA=$(get_area "$set_id")
    DIRECTORY_NAME="merge_${AREA}_${FILE_NAME}_${ENVIRONMENT}"
    MACHINE="MS${set_id}"
    WORLD_ID_LISTS="${list_worlds[$lid]}"
    WORLD_ID_LISTS_STR=${WORLD_ID_LISTS// /_}
    REMOTE_BASE_DIR="\$HOME/servers${set_id}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}"
    REMOTE_MERGE_INI="${REMOTE_BASE_DIR}/merge_setup.ini"

    echo "[Post-WorldDB] LID=${lid}, SET_ID=${set_id} ($WORLD_ID_LISTS) on $MACHINE"
    ssh "$MACHINE" "\$HOME/bin/merge_db_backup \"${REMOTE_MERGE_INI}\" _${TODAY}_Post WorldDB"
done

########################################
# 資料檢查, 合併前後差異比對
#   每個 List:
#   ssh ${MACHINE} "$HOME/bin/merge_check_v3 ... _${TODAY}_Pre _${TODAY}_Post"
########################################
for lid in "${all_lists[@]}"; do
    set_id="${list_setid[$lid]}"
    AREA=$(get_area "$set_id")
    DIRECTORY_NAME="merge_${AREA}_${FILE_NAME}_${ENVIRONMENT}"
    MACHINE="MS${set_id}"
    WORLD_ID_LISTS="${list_worlds[$lid]}"
    WORLD_ID_LISTS_STR=${WORLD_ID_LISTS// /_}
    REMOTE_BASE_DIR="\$HOME/servers${set_id}/${DIRECTORY_NAME}/${WORLD_ID_LISTS_STR}"
    REMOTE_MERGE_INI="${REMOTE_BASE_DIR}/merge_setup.ini"

    echo "[merge_check_v3] LID=${lid}, SET_ID=${set_id} ($WORLD_ID_LISTS) on $MACHINE"
    ssh "$MACHINE" "\$HOME/bin/merge_check_v3 \"${REMOTE_MERGE_INI}\" _${TODAY}_Pre _${TODAY}_Post"
done

echo "所有合併流程執行完畢。"

