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

PGGRAPH_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
# shellcheck source=../../../scripts/lib/pggraph-common.sh
source "${PGGRAPH_ROOT}/scripts/lib/pggraph-common.sh"

if [[ "${1:-}" == "--help" ]]; then
  cat <<'EOF'
Usage: run_release_gate.sh [--tier pr|nightly|rc|full-matrix] [runner options]

With no arguments, runs the stable 1.x environment-variable interface.
With --tier, delegates to scripts/run_release.py and writes JSON evidence.
EOF
  exit 0
fi

if [[ "${1:-}" == "--tier" ]]; then
  exec python3 "${PGGRAPH_ROOT}/scripts/run_release.py" "$@"
fi

if (( $# > 0 )); then
  echo "Error: unknown argument: $1" >&2
  echo "Run with --help for the supported interface." >&2
  exit 2
fi

PG_VERSION_FEATURE="${PG_VERSION_FEATURE:-pg17}"
DEVELOPMENT_FEATURES="$PG_VERSION_FEATURE development"
DB_PREFIX="${DB_PREFIX:-pggraph_release}"
pggraph_validate_database_name "${DB_PREFIX}_gate"
RUN_DOCKER="${RUN_DOCKER:-0}"
RUN_FULL_MATRIX="${RUN_FULL_MATRIX:-0}"
RUN_CRASH="${RUN_CRASH:-0}"
RUN_PGBENCH="${RUN_PGBENCH:-1}"
RUN_PACKAGE="${RUN_PACKAGE:-1}"
RUN_BOUNDARY="${RUN_BOUNDARY:-1}"
RUN_INSTALL="${RUN_INSTALL:-1}"
RUN_BACKUP_RESTORE="${RUN_BACKUP_RESTORE:-1}"
RUN_BACKGROUND_LOCK="${RUN_BACKGROUND_LOCK:-1}"
RUN_BUILD_LOCK="${RUN_BUILD_LOCK:-1}"
RUN_CONCURRENCY="${RUN_CONCURRENCY:-1}"
RUN_METADATA="${RUN_METADATA:-1}"
RUN_RSS="${RUN_RSS:-0}"
RUN_RUNTIME_RESOURCES="${RUN_RUNTIME_RESOURCES:-1}"
RUN_BUILD_MEMORY_STRESS="${RUN_BUILD_MEMORY_STRESS:-0}"
RUN_SYNTHETIC="${RUN_SYNTHETIC:-1}"
RUN_PLAYGROUND="${RUN_PLAYGROUND:-1}"
RUN_GQL_CREATE_TX="${RUN_GQL_CREATE_TX:-1}"
RUN_GQL_SET_TX="${RUN_GQL_SET_TX:-1}"
RUN_GQL_DELETE_TX="${RUN_GQL_DELETE_TX:-1}"
RUN_GQL_MERGE_RACE="${RUN_GQL_MERGE_RACE:-1}"
RUN_GQL_RELATIONSHIP_RACE="${RUN_GQL_RELATIONSHIP_RACE:-1}"
RUN_TX_DELTA_CRASH="${RUN_TX_DELTA_CRASH:-0}"
RUN_NAMED_GRAPHS_HEAVY="${RUN_NAMED_GRAPHS_HEAVY:-1}"
RUN_CROSS_BACKEND_DURABLE="${RUN_CROSS_BACKEND_DURABLE:-1}"
RUN_PROJECTION_RECOVERY="${RUN_PROJECTION_RECOVERY:-1}"
RUN_TX_DELTA_LIFECYCLE="${RUN_TX_DELTA_LIFECYCLE:-1}"
RUN_GQL_WRITE_RECHECK="${RUN_GQL_WRITE_RECHECK:-1}"
RUN_GQL_ISOLATION_MATRIX="${RUN_GQL_ISOLATION_MATRIX:-1}"
RUN_SECRETS="${RUN_SECRETS:-1}"
RUN_ALPHA_TO_V1_FIXTURE="${RUN_ALPHA_TO_V1_FIXTURE:-1}"

PYTHONDONTWRITEBYTECODE=1 python3 ../scripts/check_script_inventory.py
PYTHONDONTWRITEBYTECODE=1 python3 ../scripts/check_unsafe_allowlist.py
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=../sandbox/playground \
  python3 -m unittest discover -s ../sandbox/playground -p 'test_*.py'

if [[ "$RUN_SECRETS" == "1" ]]; then
  ../scripts/check_secrets.sh all
fi

if [[ "$RUN_FULL_MATRIX" == "1" ]]; then
  ./tests/heavy/run_pg_matrix.sh
fi

cargo fmt --check
cargo clippy --features "$DEVELOPMENT_FEATURES" --all-targets -- -D warnings
cargo doc --features "$PG_VERSION_FEATURE" --no-deps
generated_contract_schema="$(mktemp "${TMPDIR:-/tmp}/pggraph-contract-schema.XXXXXX.sql")"
trap 'rm -f "${generated_contract_schema}"' EXIT
cargo pgrx schema --features "$PG_VERSION_FEATURE" --out "$generated_contract_schema"
../scripts/check_release_contract.py --schema-file "$generated_contract_schema"
cargo test --features "$PG_VERSION_FEATURE"
cargo pgrx test --features "$DEVELOPMENT_FEATURES" "$PG_VERSION_FEATURE"
cargo deny check advisories bans licenses sources
(cd fuzz && cargo check --bins)
./fuzz/run_projection_seed_corpora.sh

if [[ "$RUN_PACKAGE" == "1" ]]; then
  PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/package_validate.sh
fi

if [[ "$RUN_INSTALL" == "1" ]]; then
  DBNAME="${DB_PREFIX}_install" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/fresh_install_smoke.sh
fi

if [[ "$RUN_ALPHA_TO_V1_FIXTURE" == "1" ]]; then
  DBNAME="${DB_PREFIX}_alpha_to_v1" ./tests/heavy/alpha_to_v1_fixture.sh all-current
fi

if [[ "$RUN_METADATA" == "1" ]]; then
  DBNAME="${DB_PREFIX}_metadata" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/function_metadata_audit.sh
fi

if [[ "$RUN_BOUNDARY" == "1" ]]; then
  DBNAME="${DB_PREFIX}_boundary" ./tests/heavy/run_sqlstate_acl_boundary.sh
fi

if [[ "$RUN_BACKUP_RESTORE" == "1" ]]; then
  SOURCE_DB="${DB_PREFIX}_backup_src" RESTORE_DB="${DB_PREFIX}_backup_dst" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/backup_restore_validate.sh
fi

if [[ "$RUN_BACKGROUND_LOCK" == "1" ]]; then
  DBNAME="${DB_PREFIX}_background_lock" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/background_job_lock_regression.sh
fi

if [[ "$RUN_BUILD_LOCK" == "1" ]]; then
  DBNAME="${DB_PREFIX}_build_lock" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/build_lock_regression.sh
fi

if [[ "$RUN_CONCURRENCY" == "1" ]]; then
  DBNAME="${DB_PREFIX}_concurrency" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/concurrency_stress.sh
fi

if [[ "$RUN_SYNTHETIC" == "1" ]]; then
  DBNAME="${DB_PREFIX}_synthetic" \
    NODE_COUNT="${SYNTHETIC_NODE_COUNT:-50000}" \
    HUB_FANOUT="${SYNTHETIC_HUB_FANOUT:-1000}" \
    MAX_BUILD_MS="${SYNTHETIC_MAX_BUILD_MS:-60000}" \
    MAX_QUERY_MS="${SYNTHETIC_MAX_QUERY_MS:-1000}" \
    ./tests/heavy/synthetic_release_smoke.sh
fi

if [[ "$RUN_PLAYGROUND" == "1" ]]; then
  PGGRAPH_PLAYGROUND_YES="${PGGRAPH_PLAYGROUND_YES:-1}" \
    PGGRAPH_REBUILD_IMAGE=1 \
    PGGRAPH_RECREATE_CONTAINER=1 \
    ./tests/heavy/playground_release_gate.sh
fi

if [[ "$RUN_PGBENCH" == "1" ]]; then
  DBNAME="${DB_PREFIX}_pgbench" CLIENTS="${CLIENTS:-4}" JOBS="${JOBS:-2}" TIME="${TIME:-30}" ./tests/heavy/run_pgbench_sync.sh
fi

if [[ "$RUN_GQL_CREATE_TX" == "1" ]]; then
  DBNAME="${DB_PREFIX}_gql_create_tx" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/gql_create_tx_lifecycle.sh
fi

if [[ "$RUN_GQL_SET_TX" == "1" ]]; then
  DBNAME="${DB_PREFIX}_gql_set_tx" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/gql_set_tx_lifecycle.sh
fi

if [[ "$RUN_GQL_DELETE_TX" == "1" ]]; then
  DBNAME="${DB_PREFIX}_gql_delete_tx" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/gql_delete_tx_lifecycle.sh
fi

if [[ "$RUN_GQL_MERGE_RACE" == "1" ]]; then
  DBNAME="${DB_PREFIX}_gql_merge_race" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/gql_merge_race.sh
fi

if [[ "$RUN_GQL_RELATIONSHIP_RACE" == "1" ]]; then
  DBNAME="${DB_PREFIX}_gql_relationship_race" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/gql_relationship_race.sh
fi

if [[ "$RUN_RSS" == "1" ]]; then
  DBNAME="${DB_PREFIX}_rss" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/measure_build_rss.sh
fi

if [[ "$RUN_RUNTIME_RESOURCES" == "1" ]]; then
  DBNAME="${DB_PREFIX}_runtime_resources" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/measure_runtime_resources.sh
fi

if [[ "$RUN_BUILD_MEMORY_STRESS" == "1" ]]; then
  DB_PREFIX="${DB_PREFIX}_memstress" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" ./tests/heavy/build_memory_stress.sh
fi

if [[ "$RUN_CRASH" == "1" ]]; then
  : "${PGDATA:?PGDATA must point at a disposable cluster when RUN_CRASH=1}"
  DBNAME="${DB_PREFIX}_crash" PGDATA="$PGDATA" ./tests/heavy/crash_recovery.sh
fi

if [[ "$RUN_TX_DELTA_CRASH" == "1" ]]; then
  : "${PGDATA:?PGDATA must point at a disposable cluster when RUN_TX_DELTA_CRASH=1}"
  DBNAME="${DB_PREFIX}_tx_delta_crash" PGDATA="$PGDATA" ./tests/heavy/tx_delta_crash_recovery.sh
fi

if [[ "$RUN_NAMED_GRAPHS_HEAVY" == "1" ]]; then
  DBNAME="${DB_PREFIX}_named_graphs" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" bash ./tests/heavy/named_graphs_heavy_gate.sh
fi

if [[ "$RUN_CROSS_BACKEND_DURABLE" == "1" ]]; then
  DBNAME="${DB_PREFIX}_cross_backend" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" bash ./tests/heavy/cross_backend_durable_projection.sh
fi

if [[ "$RUN_PROJECTION_RECOVERY" == "1" ]]; then
  DBNAME="${DB_PREFIX}_projection_rec" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" bash ./tests/heavy/projection_recovery_gate.sh
fi

if [[ "$RUN_TX_DELTA_LIFECYCLE" == "1" ]]; then
  DBNAME="${DB_PREFIX}_tx_delta" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" bash ./tests/heavy/tx_delta_lifecycle.sh
fi

if [[ "$RUN_GQL_WRITE_RECHECK" == "1" ]]; then
  DBNAME="${DB_PREFIX}_gql_write_recheck" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" bash ./tests/heavy/gql_write_recheck_race.sh
fi

if [[ "$RUN_GQL_ISOLATION_MATRIX" == "1" ]]; then
  DBNAME="${DB_PREFIX}_gql_isolation" PG_VERSION_FEATURE="$PG_VERSION_FEATURE" bash ./tests/heavy/gql_isolation_matrix.sh
fi

if [[ "$RUN_DOCKER" == "1" ]]; then
  ./tests/heavy/docker_smoke.sh
fi

echo "Release gate passed for $PG_VERSION_FEATURE"
