#!/usr/bin/env bash
# Replikasi sinkron dengan quorum: synchronous_standby_names 'ANY 1 (...)'.
# Primary port 54371, standby port 54372, database toko.
# Skrip ini mandiri: membersihkan dirinya sendiri di akhir.
set -eu

PGBIN=/home/z/my-project/tools/dl/pgdeb/usr/lib/postgresql/17/bin
BASE=/home/z/my-project/tmp/rp_ha
PRI=$BASE/pgdata_pusat     # primary, port 54371
STD=$BASE/pgdata_cabang    # standby,  port 54372
SOCK=$BASE/sock

bersihkan() {
  "$PGBIN/pg_ctl" -D "$PRI" -m immediate stop >/dev/null 2>&1 || true
  "$PGBIN/pg_ctl" -D "$STD" -m immediate stop >/dev/null 2>&1 || true
  rm -rf "$BASE"
}
trap bersihkan EXIT

# Buang sisa percobaan sebelumnya bila ada.
bersihkan
mkdir -p "$SOCK"

# Polling: tunggu sampai sebuah query mengembalikan nilai yang diharapkan.
tunggu() {  # port database sql nilai_yang_diharapkan
  local port="$1" db="$2" sql="$3" harapan="$4" i hasil
  for i in $(seq 1 150); do
    hasil=$(psql -X -q -t -A -h 127.0.0.1 -p "$port" -U postgres -d "$db" \
            -c "$sql" 2>/dev/null) || true
    if [ "$hasil" = "$harapan" ]; then return 0; fi
    sleep 0.2
  done
  echo "TIMEOUT: menunggu '$sql' menjadi $harapan (port $port)" >&2
  return 1
}

echo "== Langkah 1: siapkan pasangan primary (54371) dan standby (54372) =="
"$PGBIN/initdb" -D "$PRI" --no-locale -E UTF8 -U postgres >/dev/null 2>&1
"$PGBIN/pg_ctl" -D "$PRI" \
  -o "-p 54371 -k $SOCK -c listen_addresses=127.0.0.1" \
  -l "$BASE/primary.log" start >/dev/null 2>&1
tunggu 54371 postgres "SELECT 1;" "1"
psql -X -h 127.0.0.1 -p 54371 -U postgres -d postgres \
  -c "CREATE DATABASE toko;"
psql -X -h 127.0.0.1 -p 54371 -U postgres -d toko \
  -c "CREATE TABLE produk (id int PRIMARY KEY, nama text, harga numeric);" \
  -c "INSERT INTO produk VALUES (1, 'Kopi Tubruk', 15000), (2, 'Teh Celup', 8000);"
PGDATABASE=postgres pg_basebackup -h 127.0.0.1 -p 54371 -U postgres \
  -D "$STD" -R -X stream -c fast >/dev/null 2>&1
"$PGBIN/pg_ctl" -D "$STD" \
  -o "-p 54372 -k $SOCK -c listen_addresses=127.0.0.1 -c cluster_name=standby_cabang" \
  -l "$BASE/standby.log" start >/dev/null 2>&1
tunggu 54372 toko "SELECT count(*) FROM produk;" "2"
echo "pasangan siap dalam mode bawaan (asinkron)"

echo "== Langkah 2: keadaan awal — belum ada standby sinkron =="
psql -X -h 127.0.0.1 -p 54371 -U postgres -d toko \
  -c "SHOW synchronous_standby_names;" \
  -c "SELECT application_name, state, sync_state FROM pg_stat_replication;"

echo "== Langkah 3: nyalakan mode sinkron quorum =="
psql -X -h 127.0.0.1 -p 54371 -U postgres -d toko \
  -c "ALTER SYSTEM SET synchronous_standby_names = 'ANY 1 (standby_cabang)';" \
  -c "SELECT pg_reload_conf();"
tunggu 54371 toko \
  "SELECT sync_state FROM pg_stat_replication WHERE application_name = 'standby_cabang';" \
  "quorum"
echo "standby kini berstatus quorum"

echo "== Langkah 4: keadaan sesudah — commit menunggu flush standby =="
psql -X -h 127.0.0.1 -p 54371 -U postgres -d toko \
  -c "SHOW synchronous_standby_names;" \
  -c "SHOW synchronous_commit;" \
  -c "SELECT application_name, state, sync_state FROM pg_stat_replication;"

echo "== Langkah 5: tulisan tetap mengalir, kini dengan jaminan quorum =="
psql -X -h 127.0.0.1 -p 54371 -U postgres -d toko \
  -c "INSERT INTO produk VALUES (3, 'Gula Pasir', 12000);"
tunggu 54372 toko "SELECT count(*) FROM produk;" "3"
psql -X -h 127.0.0.1 -p 54372 -U postgres -d toko \
  -c "SELECT id, nama, harga FROM produk ORDER BY id;"
