#!/bin/bash
[ "$1" == "" ] && exec echo "Usage: $0 <TABLE_NAME>"

source $HOME/.gamerc

SCRIPT_NAME=$(basename "$0")
LOCK_FILE="${HOME}/www/tools/files/.${SCRIPT_NAME}.lock"

exec 200>"${LOCK_FILE}"
flock -n 200 || {
    echo "${SCRIPT_NAME} is running. Exiting."
    exit 1
}

TABLE_NAME=$1

get_table_primay_key_orders () {
    TABLE_NAME=$1
    RETURN=$(psql -U postgres -Atq ${GAME_TYPE}Account_X -c "
        SELECT a.attnum
        FROM pg_index i
        JOIN pg_class t ON t.oid = i.indrelid
        JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(i.indkey)
        WHERE i.indisprimary
          AND t.relname = '${TABLE_NAME}'
          AND pg_catalog.pg_table_is_visible(t.oid)
        ORDER BY a.attnum;
    " | tr '\n' ' ' | sed 's/[[:space:]]\+$//')
    echo ${RETURN}
}

# 找可用的 unique index（第一個找到的）
get_table_unique_key_orders () {
    TABLE_NAME=$1
    RETURN=$(psql -U postgres -Atq ${GAME_TYPE}Account_X -c "
        WITH u AS (
            SELECT i.indkey
            FROM pg_index i
            JOIN pg_class t ON t.oid = i.indrelid
            WHERE t.relname = '${TABLE_NAME}'
              AND pg_catalog.pg_table_is_visible(t.oid)
              AND i.indisunique = true
            ORDER BY i.indisprimary DESC, i.indexrelid
            LIMIT 1
        )
        SELECT string_agg((u.indkey[s.i])::text, ' ' ORDER BY s.i)
        FROM u
        JOIN generate_subscripts(u.indkey, 1) s(i) ON true
        WHERE u.indkey[s.i] > 0;
    " | tr '\n' ' ' | sed 's/[[:space:]]\+$//')
    echo ${RETURN}
}

# 從 diff.content 推導「前 k 欄」可唯一識別（最後 fallback 用）
infer_key_prefix_k () {
    local input="$1"
    awk '
    function build_key(f, k,    i, s) {
        s = f[1]
        for (i=2; i<=k; i++) s = s " " f[i]
        return s
    }
    BEGIN { maxk=10 }
    {
        sub(/^[><][ \t]+/, "", $0)
        n = split($0, f, /[ \t]+/)
        if (n < 1) next
        for (k=1; k<=maxk && k<=n; k++) {
            key = build_key(f, k)
            if (++seen[k, key] > 1) dup[k]=1
            cnt[k]++
        }
    }
    END {
        for (k=1; k<=maxk; k++) {
            if (cnt[k] > 0 && !(k in dup)) { print k; exit }
        }
        print 1
    }' "$input"
}

rm -rf ${HOME}/www/tools/files/itemmall_web/${TABLE_NAME}.diff*;

mkdir -p ${HOME}/www/tools/files/itemmall_web/test/;
cd ${HOME}/www/tools/files/itemmall_web/test;
echo "Dump ${TABLE_NAME} on TEST ...";
pg_dump -U postgres ${GAME_TYPE}Account_X -t ${TABLE_NAME} | sed '/^\\unrestrict /d' | sed '/^\\restrict /d' | sed '/^$/d' | sort > ${TABLE_NAME}_testbackup_new_current.sql

ssh ACCOUNTDB "echo 'Dump ${TABLE_NAME} on LIVE ...'; pg_dump -U postgres ${GAME_TYPE}Account_X -t ${TABLE_NAME} | sed '/^\\\\unrestrict /d' | sed '/^\\\\restrict /d' | sed '/^$/d' | sort > /tmp/${TABLE_NAME}_livebackup_old_current.sql"
mkdir -p ${HOME}/www/tools/files/itemmall_web/live/;
cd ${HOME}/www/tools/files/itemmall_web/live;
rsync -avz ACCOUNTDB:/tmp/${TABLE_NAME}_livebackup_old_current.sql . >/dev/null 2>&1

cd ${HOME}/www/tools/files/itemmall_web

input_file="${TABLE_NAME}.diff.content"
pkey_file="${TABLE_NAME}.diff.pkey"
modify_file="${TABLE_NAME}.diff.content.modify"
new_file="${TABLE_NAME}.diff.content.new"
delete_file="${TABLE_NAME}.diff.content.delete"
output_file="${TABLE_NAME}.diff.output"

diff test/${TABLE_NAME}_testbackup_new_current.sql live/${TABLE_NAME}_livebackup_old_current.sql \
| grep -E -a -v 'Dump' | grep -E -a '<|>' > ${input_file}
cat ${input_file}

# === 決定 key 欄位（重要修正）===
if [ "${TABLE_NAME}" = "cheat_detection_rankstage" ]; then
    # 指定以 min_payment(第1欄) + max_payment(第2欄) 當 key
    pkey_search="1 2"
else
    pkey_search=$(get_table_primay_key_orders ${TABLE_NAME})
fi

# 防呆：只保留 >=1 的數字欄位序
pkey_search=$(echo "$pkey_search" | awk '{for(i=1;i<=NF;i++) if($i ~ /^[0-9]+$/ && $i >= 1) printf "%s ", $i}')
pkey_search=$(echo "$pkey_search" | sed 's/[[:space:]]\+$//')

# 若仍抓不到 key（無 PK/無指定），嘗試 unique index，再不行就從 diff 推導
if [ "$pkey_search" = "" ]; then
    pkey_search=$(get_table_unique_key_orders ${TABLE_NAME})
    pkey_search=$(echo "$pkey_search" | awk '{for(i=1;i<=NF;i++) if($i ~ /^[0-9]+$/ && $i >= 1) printf "%s ", $i}')
    pkey_search=$(echo "$pkey_search" | sed 's/[[:space:]]\+$//')
fi

if [ "$pkey_search" = "" ]; then
    k=$(infer_key_prefix_k "$input_file")
    pkey_search=$(awk -v k="$k" 'BEGIN{for(i=1;i<=k;i++) printf i (i<k?" ":"");}')
fi

echo "KEY cols = [$pkey_search]"

# === Step 1: Extract unique keys ===
awk -v cols="$pkey_search" '
function make_key(fields, cols,    i, idx, n, key) {
    n = split(cols, idx, /[ \t]+/)
    key = ""
    for (i = 1; i <= n; i++) {
        if (idx[i] == "") continue
        key = key (key == "" ? "" : " ") fields[idx[i]]
    }
    return key
}
{
    sub(/^[><][ \t]+/, "", $0)
    split($0, fields, /[ \t]+/)
    key = make_key(fields, cols)
    if (key != "" && !(key in seen)) {
        seen[key] = 1
        print key
    }
}
' "$input_file" | sort -u > "$pkey_file"
cat ${pkey_file}

echo "====== Modify ======" > ${modify_file}
echo "====== New ======" > ${new_file}
echo "====== Delete ======" > ${delete_file}

# === Step 2: Process each key ===
if [ -s "${pkey_file}" ]; then
    while IFS= read -r key; do
        awk -v key="$key" -v cols="$pkey_search" '
        function match_key(fields, key, cols,    i, idx, n, val, m) {
            n = split(cols, idx, /[ \t]+/)
            m = split(key,  val, /[ \t]+/)
            for (i = 1; i <= n; i++) {
                if (idx[i] == "") continue
                if (fields[idx[i]] != val[i]) return 0
            }
            return 1
        }
        {
            raw = $0
            line = raw
            sub(/^[><][ \t]+/, "", line)
            split(line, fields, /[ \t]+/)

            if (match_key(fields, key, cols)) {
                if (raw ~ /^</) before = raw
                if (raw ~ /^>/) after  = raw
            }
        }
        END {
            if (before && after) {
                print key >> "'"$modify_file"'"
                print after >> "'"$modify_file"'"
                print before >> "'"$modify_file"'"
            } else if (before) {
                print key >> "'"$new_file"'"
                print before >> "'"$new_file"'"
            } else if (after) {
                print key >> "'"$delete_file"'"
                print after >> "'"$delete_file"'"
            }
        }
        ' "$input_file"
    done < "$pkey_file"
fi

[ -f "${output_file}" ] && rm -rf ${output_file}
echo >> ${output_file}
cat ${new_file} >> ${output_file}
echo >> ${output_file}
cat ${modify_file} >> ${output_file}
echo >> ${output_file}
cat ${delete_file} >> ${output_file}

cat ${output_file}

[ -f "${LOCK_FILE}" ] && rm -rf ${LOCK_FILE}

