#!/usr/bin/env bash
# Backup-restore-övning (hardening-checklistan: "genomfört och protokollfört, kvartalsvis").
# Kör: DATABASE_URL=postgres://… ./infrastructure/deployment/backup-restore-test.sh
#
# Gör: logisk dump → återställ till temporär databas → jämför radantal per tabell
# → skriv protokoll → städa. Avslutar med exitkod 1 vid avvikelse.
set -euo pipefail

DATABASE_URL="${DATABASE_URL:?Sätt DATABASE_URL}"
# Roll med CREATEDB för test-databasen (RDS master/operatör). Faller tillbaka på DATABASE_URL.
ADMIN_URL="${ADMIN_DATABASE_URL:-$DATABASE_URL}"
STAMP=$(date +%Y%m%d_%H%M%S)
WORKDIR="${BACKUP_DIR:-/tmp/backup-restore-test}"
DUMP="$WORKDIR/dump-$STAMP.pgdump"
RESTORE_DB="restore_test_$STAMP"
PROTOKOLL="$WORKDIR/protokoll-$STAMP.md"
mkdir -p "$WORKDIR"

# Härled anslutning utan databasnamn för att kunna skapa/droppa test-databasen.
BASE_URL="${DATABASE_URL%/*}"
ADMIN_BASE_URL="${ADMIN_URL%/*}"

echo "==> 1/5 Dumpar databasen"
pg_dump "$DATABASE_URL" --format=custom --file="$DUMP"
SIZE=$(du -h "$DUMP" | cut -f1)

echo "==> 2/5 Skapar temporär databas $RESTORE_DB"
psql "$ADMIN_BASE_URL/postgres" -qc "CREATE DATABASE $RESTORE_DB" 2>/dev/null \
  || psql "$ADMIN_URL" -qc "CREATE DATABASE $RESTORE_DB"

cleanup() {
  psql "$ADMIN_BASE_URL/postgres" -qc "DROP DATABASE IF EXISTS $RESTORE_DB" 2>/dev/null \
    || psql "$ADMIN_URL" -qc "DROP DATABASE IF EXISTS $RESTORE_DB" || true
}
trap cleanup EXIT

echo "==> 3/5 Återställer till $RESTORE_DB"
# Återställ som admin-rollen (äger test-databasen, får skapa extensions).
pg_restore --dbname="$ADMIN_BASE_URL/$RESTORE_DB" --no-owner --no-privileges "$DUMP"

echo "==> 4/5 Jämför radantal per tabell"
COUNT_SQL="SELECT relname, n_live_tup FROM pg_stat_user_tables ORDER BY relname"
ROWS_SQL="SELECT string_agg(format('%s:%s', t.tablename, (xpath('/row/cnt/text()', query_to_xml(format('SELECT count(*) AS cnt FROM %I', t.tablename), false, true, '')))[1]::text), E'\n' ORDER BY t.tablename) FROM pg_tables t WHERE schemaname='public'"
ORIG=$(psql "$DATABASE_URL" -tA -c "$ROWS_SQL")
REST=$(psql "$ADMIN_BASE_URL/$RESTORE_DB" -tA -c "$ROWS_SQL")

STATUS="GODKÄND"
DIFF_OUT=""
if [ "$ORIG" != "$REST" ]; then
  STATUS="UNDERKÄND"
  DIFF_OUT=$(diff <(echo "$ORIG") <(echo "$REST") || true)
fi

echo "==> 5/5 Skriver protokoll: $PROTOKOLL"
TABLES=$(echo "$ORIG" | wc -l)
TOTAL=$(echo "$ORIG" | awk -F: '{s+=$2} END {print s}')
{
  echo "# Backup-restore-protokoll $STAMP"
  echo
  echo "| Fält | Värde |"
  echo "| ---- | ----- |"
  echo "| Resultat | **$STATUS** |"
  echo "| Dumpstorlek | $SIZE |"
  echo "| Tabeller jämförda | $TABLES |"
  echo "| Totalt antal rader | $TOTAL |"
  echo "| Dump | $DUMP |"
  echo
  if [ -n "$DIFF_OUT" ]; then
    echo '## Avvikelser'
    echo '```'
    echo "$DIFF_OUT"
    echo '```'
  else
    echo "Alla tabellers radantal identiska mellan original och återställning."
  fi
} > "$PROTOKOLL"

cat "$PROTOKOLL"
[ "$STATUS" = "GODKÄND" ]
