#!/usr/bin/env bash
# The refusal path of the table write path and the upgrade path from 3.0.1: a sift_table that has had rows with their own versions (unfrozen groups, column format 1.4,
# on-disk format 1.3) is refused with a format error, and returns no row, by a server that loads the older library (3.0.1, built from
# the repository by scripts/old-lib-check.sh and kept in the build cache of old-lib-check.sh). Skipped when that library cannot be built here:
# no v3.0.1 in the repository, or PostgreSQL 17 (no extension_control_path to hold two builds).
. "$(dirname "$0")/lib.bash"

REPO=$(cd "$(dirname "$0")/../.." && pwd)
# A cold released build must own its install, even inside a lane sharing the current root.
# Reuse that build for the refusal and upgrade checks below.
export SIFT_OLD_DIR="$TAPDIR/old-lib-cache"
parent="$TAPDIR/old-lib-parent"
rm -rf "$SIFT_OLD_DIR" "$parent"
mkdir -p "$parent$(pg_config --pkglibdir)" "$parent$(pg_config --sharedir)/extension"
files=("$parent/.flavor" "$parent$(pg_config --pkglibdir)/pg_sift$DLSUFFIX" "$parent$(pg_config --sharedir)/extension/pg_sift.control")
for file in "${files[@]}"; do echo current-testing-install >"$file"; done
before=$("$REPO/scripts/sha256.sh" "${files[@]}")
root=$(SIFT_ROOT="$parent" "$REPO/scripts/old-lib-check.sh" build)
rc=$?
if ((rc == 77)); then echo '1..0 # SKIP older library unavailable'; exit 0; fi
((rc == 0)) || bail 'cold released build failed'
check 'released build preserves the inherited install' test "$("$REPO/scripts/sha256.sh" "${files[@]}")" == "$before"
check 'released build returns its private root' test "$root" == "$SIFT_OLD_DIR/root"
check 'released root contains its flavor' test -f "$root/.flavor"
check 'released root contains its library' test -f "$root$(pg_config --pkglibdir)/pg_sift$DLSUFFIX"
check 'released root contains its control file' test -f "$root$(pg_config --sharedir)/extension/pg_sift.control"
((NFAIL == 0)) || bail 'released install escaped its root'
rm -rf "$parent"

# the cluster of the script on a port of its own, in the directory of the other nodes (removed when it ends)
out=$(SIFT_TMP="$TAPDIR/old-lib" SIFT_PORT=$((SIFT_PORT + 15)) "$REPO/scripts/old-lib-check.sh" run 2>&1)
rc=$?
if ((rc != 77)); then # and the other way: the groups the older library tags under pressure are read, frozen or dropped
	out+=$'\n'$(SIFT_TMP="$TAPDIR/old-lib-up" SIFT_PORT=$((SIFT_PORT + 16)) "$REPO/scripts/old-lib-check.sh" upgrade 2>&1)
	# and the point directories of 3.6 (a power of two of slots) beside the exact count of this tree, in its own cached build of 3.6.0
	out+=$'\n'$(env -u SIFT_OLD_DIR SIFT_OLD_REF=v3.6.0 SIFT_TMP="$TAPDIR/old-lib-pt" SIFT_PORT=$((SIFT_PORT + 17)) "$REPO/scripts/old-lib-check.sh" points 2>&1)
	# and the global orders of 3.6 (addresses of 9 bits) beside the packed addresses of this tree
	out+=$'\n'$(env -u SIFT_OLD_DIR SIFT_OLD_REF=v3.6.0 SIFT_TMP="$TAPDIR/old-lib-go" SIFT_PORT=$((SIFT_PORT + 19)) "$REPO/scripts/old-lib-check.sh" gorder 2>&1)
	# and the INCLUDE columns of this tree (segment format 5, minor 1.5) beside the plain index of 3.7.0
	out+=$'\n'$(env -u SIFT_OLD_DIR SIFT_OLD_REF=v3.7.0 SIFT_TMP="$TAPDIR/old-lib-inc" SIFT_PORT=$((SIFT_PORT + 20)) "$REPO/scripts/old-lib-check.sh" include 2>&1)
	# and the key-cut units of 3.6 (the chunk table after the directory) beside the table first of this tree
	out+=$'\n'$(env -u SIFT_OLD_DIR SIFT_OLD_REF=v3.6.0 SIFT_TMP="$TAPDIR/old-lib-kc" SIFT_PORT=$((SIFT_PORT + 18)) "$REPO/scripts/old-lib-check.sh" keyed 2>&1)
	# and the logs of 4.0.0 to 4.1.1, which may count row versions that were updated: this tree re-baselines them, and the older library reads the result as the heap
	out+=$'\n'$(env -u SIFT_OLD_DIR SIFT_OLD_REF=v4.1.0 SIFT_TMP="$TAPDIR/old-lib-track" SIFT_PORT=$((SIFT_PORT + 21)) "$REPO/scripts/old-lib-check.sh" track 2>&1)
	# and the presence leaf of 4.2 (a jsonb column that may hold a NULL document): every release family refuses the index, and REINDEX under the release is the way back
	for ref in v3.2.3 v4.0.5 v4.1.4; do
		out+=$'\n'$(env -u SIFT_OLD_DIR SIFT_OLD_REF=$ref SIFT_TMP="$TAPDIR/old-lib-pr-$ref" SIFT_PORT=$((SIFT_PORT + 22)) "$REPO/scripts/old-lib-check.sh" present 2>&1 | sed "s/^\(PASS\|FAIL\) /\1 $ref: /")
	done
fi
if ((rc == 77)); then
	echo "1..0 # SKIP $(grep -h '^SKIP ' <<<"$out" | head -1 | sed 's/^SKIP //')"
	exit 0
fi
while IFS= read -r line; do
	case $line in
		"PASS "*) ok "${line#PASS }" ;;
		"FAIL "*) not_ok "${line#FAIL }" ;;
		*) [[ -z $line ]] || diag "$line" ;;
	esac
done <<<"$out"
((rc == 0 || NFAIL > 0)) || not_ok "scripts/old-lib-check.sh run failed (exit $rc)"
((NTEST > 0)) || not_ok "scripts/old-lib-check.sh run produced no result"
echo "1..$NTEST"
finish
