#!/usr/bin/env bash
#
# scripts/run-regress.sh - minimal pg_regress substitute.
#
# Our nix-built pg_regress has a broken exec path for /bin/sh in
# child processes.  This driver replicates what pg_regress does:
# drop/create a throwaway database, run each test .sql through psql,
# capture output, and diff against expected.
#
# Usage: scripts/run-regress.sh [test_name ...]
#        defaults to "pg_tre".

set -euo pipefail

cd "$(dirname "$0")/.."

PG_CONFIG="${PG_CONFIG:-pg_config}"
BINDIR=$("$PG_CONFIG" --bindir)
PSQL="$BINDIR/psql"
DROPDB="$BINDIR/dropdb"
CREATEDB="$BINDIR/createdb"

DBNAME="${DBNAME:-contrib_regression}"

TESTS=("$@")
if [ ${#TESTS[@]} -eq 0 ]; then TESTS=(pg_tre scan_exact incremental p5_read planner planner_auto p6_safety utf8 dnf_resolution sparsemap_serialize multi_leaf similarity trgm_similarity like_accel word_similarity selectivity order_by concurrently cardinality upgrade vacuum_inline posting_recycle multi_level_merge run_catalog build_estimate build_dedup flush_to_run crack_on_read coalesce coalesce_vacuum coalesce_density density_scaling vacuum_repack reloptions testregex custom_costs utf8_fuzzy amvalidate parallel_build upgrade_online surf_prefix pending_reclaim merge_page_reclaim churned_heap_scan sparsemap_corrupt_guard sparsemap_smallset similarity_multibyte vacuum_pending_dead pending_distinct collation_guard encoding_nonutf8 regex_class_index encoding_matrix collation_matrix tre_ctype_strategies regex_syntax_edges tre_collation_classes tre_upstream_fixes rep_extract regex_groups_index class_pieces tid_packing pending_limit); fi

mkdir -p test/results
rm -f test/results/*.out test/results/*.diff

"$DROPDB" --if-exists "$DBNAME" >/dev/null
# CREATEDB_OPTS: e.g. "-T template0 -E UTF8 --locale=C.UTF-8" (CI runs both).
"$CREATEDB" ${CREATEDB_OPTS:-} "$DBNAME"

fail=0
for t in "${TESTS[@]}"; do
    sql="test/sql/${t}.sql"
    expected="test/expected/${t}.out"
    actual="test/results/${t}.out"
    if [[ ! -f "$sql" ]]; then
        echo "missing test file: $sql" >&2
        fail=1; continue
    fi
    "$PSQL" -d "$DBNAME" -X -a -f "$sql" > "$actual" 2>&1 || true

    if [[ ! -f "$expected" ]]; then
        echo "no expected file -- creating from current output: $expected"
        cp "$actual" "$expected"
        echo "ok  $t (generated expected)"
        continue
    fi

    # Like pg_regress: test/expected/<t>_N.out are alternative outputs
    # (e.g. a PostgreSQL major that lacks a feature the test uses).
    matched=
    for e in "$expected" test/expected/"${t}"_[0-9].out; do
        if [[ -f "$e" ]] && diff -q "$e" "$actual" >/dev/null; then
            matched=$e
            break
        fi
    done
    if [[ -n "$matched" ]]; then
        rm -f "test/results/${t}.diff"
        echo "ok  $t"
    else
        diff -u "$expected" "$actual" > "test/results/${t}.diff" || true
        echo "FAIL $t"
        sed -n '1,200p' "test/results/${t}.diff"
        fail=1
    fi
done

exit "$fail"
