#!/usr/bin/env bash
# Regression test for tools/lib/release-stamp.sh.
# Usage: tools/tests/release-stamp.test.sh
#
# The stamp functions rewrite files that hold irreplaceable history and this repo has no
# git, so the property that matters most is the one asserted the most here: everything
# outside the machine block comes out byte-identical. Runs entirely on copies under
# tools/tests/.work/ — it never writes to a plugin.
set -uo pipefail

SCRATCH="$(cd "$(dirname "$0")" && pwd)/.work"
LIB="$(cd "$(dirname "$0")/../.." && pwd)/tools/lib/release-stamp.sh"
PLUGINS="$(cd "$(dirname "$0")/../.." && pwd)/wp-content/plugins"

rm -rf "$SCRATCH"; mkdir -p "$SCRATCH"
# shellcheck source=/dev/null
source "$LIB"

PASS=0; FAIL=0
ok()   { PASS=$((PASS+1)); printf '  \033[0;32mPASS\033[0m %s\n' "$1"; }
bad()  { FAIL=$((FAIL+1)); printf '  \033[0;31mFAIL\033[0m %s\n' "$1"; }
check(){ if eval "$2"; then ok "$1"; else bad "$1  [$2]"; fi; }

hdr() { printf '\n\033[1m== %s\033[0m\n' "$1"; }

# Copy a real doc with any existing machine block stripped, so the "fresh insert" cases
# below test the fresh path no matter whether the repo has been backfilled yet.
virgin_copy() {
	awk '
		/BW-RELEASES:BEGIN|BW-RELEASE-STATUS:BEGIN/ { skip = 1; next }
		skip && /BW-RELEASES:END|BW-RELEASE-STATUS:END/ { skip = 2; next }
		skip == 1 { next }
		skip == 2 && /^$/ { skip = 0; next }   # the blank line we insert after a block
		{ skip = 0; print }
	' "$1" > "$2"
}

# ---------------------------------------------------------------- fresh ledger
for slug in bw-lead-ai bw-guides bw-dev bw-interlink bw-2checkout-pricing bw-map-magnet bw-video-text bw-ai-schema-pro; do
	hdr "fresh ledger: $slug"
	virgin_copy "$PLUGINS/$slug/docs/SESSION-LOG.md" "$SCRATCH/$slug.orig"
	src="$SCRATCH/$slug.orig"
	cp "$src" "$SCRATCH/$slug.SESSION-LOG.md"
	f="$SCRATCH/$slug.SESSION-LOG.md"
	before=$(wc -l < "$f")

	bw_stamp_session_log "$f" "9.9.9" "2026-08-11T12:00:00Z" "abcdef0123456789abcdef0123456789"
	rc=$?
	check "returns OK"                 "[[ $rc -eq 0 ]]"
	check "ledger present"             "grep -qF '## Releases' '$f'"
	check "stamp line present"         "grep -qF '> RELEASED 9.9.9 — 2026-08-11T12:00:00Z, sha256:abcdef0123456789' '$f'"
	check "grew by exactly 11 lines"   "[[ \$(wc -l < '$f') -eq $((before+11)) ]]"
	check "title line untouched"       "[[ \"\$(head -1 '$f')\" == \"\$(head -1 '$src')\" ]]"
	# Everything that isn't the new block must be byte-identical to the original.
	sed '/BW-RELEASES:BEGIN/,/BW-RELEASES:END/d' "$f" | sed '${/^$/d}' > "$SCRATCH/$slug.stripped"
	# the block is followed by one blank line we also added
	diff <(cat "$src") <(awk 'BEGIN{skip=0} /BW-RELEASES:BEGIN/{skip=1} skip==1 && /BW-RELEASES:END/{skip=2; next} skip==1{next} skip==2 && /^$/{skip=0; next} {print}' "$f") > "$SCRATCH/$slug.diff"
	check "prose byte-identical"       "[[ ! -s '$SCRATCH/$slug.diff' ]]"

	# ledger must sit before the first session entry (a '## ' heading that is a date)
	led=$(grep -n '^## Releases' "$f" | head -1 | cut -d: -f1)
	ent=$(awk '/^(```|~~~)/{fence=!fence; next} fence{next} /^## 2[0-9]{3}-/{print NR; exit}' "$f")
	check "ledger above first entry"   "[[ -n '$ent' && $led -lt $ent ]]"
done

# ------------------------------------------------------- second + repeat release
hdr "second release, then a re-publish of the same version"
f="$SCRATCH/bw-lead-ai.SESSION-LOG.md"
bw_stamp_session_log "$f" "9.9.10" "2026-08-11T13:00:00Z" "1111111111111111aaaa"
check "newest line is on top" \
	"[[ \"\$(grep -m1 '^> RELEASED' '$f')\" == '> RELEASED 9.9.10 — 2026-08-11T13:00:00Z, sha256:1111111111111111' ]]"
check "older line retained"          "grep -qF '> RELEASED 9.9.9 —' '$f'"
check "two ledger lines"             "[[ \$(grep -c '^> RELEASED' '$f') -eq 2 ]]"

bw_stamp_session_log "$f" "9.9.9" "2026-08-11T14:00:00Z" "2222222222222222bbbb"
check "re-publish did not duplicate" "[[ \$(grep -c '^> RELEASED' '$f') -eq 2 ]]"
check "re-publish replaced the line" "grep -qF '> RELEASED 9.9.9 — 2026-08-11T14:00:00Z, sha256:2222222222222222' '$f'"
check "old sha for 9.9.9 gone"       "! grep -qF 'sha256:abcdef0123456789' '$f'"
check "9.9.9 moved to top"           "[[ \"\$(grep -m1 '^> RELEASED' '$f')\" == '> RELEASED 9.9.9 — 2026-08-11T14:00:00Z, sha256:2222222222222222' ]]"
check "still exactly one block"      "[[ \$(grep -c 'BW-RELEASES:BEGIN' '$f') -eq 1 ]]"

# 1.8.6 must not be matched by a regex built from 1.8.60 or vice versa
bw_stamp_session_log "$f" "9.9.1" "2026-08-11T15:00:00Z" "3333333333333333cccc"
bw_stamp_session_log "$f" "9.9.11" "2026-08-11T16:00:00Z" "4444444444444444dddd"
check "9.9.1 not eaten by 9.9.11"    "grep -qF '> RELEASED 9.9.1 —' '$f'"
check "four distinct versions"       "[[ \$(grep -c '^> RELEASED' '$f') -eq 4 ]]"

# --------------------------------------------------------------- handoff banner
for slug in bw-lead-ai bw-guides bw-dev; do
	hdr "handoff banner: $slug"
	virgin_copy "$PLUGINS/$slug/docs/HANDOFF-NOTES.md" "$SCRATCH/$slug.horig"
	src="$SCRATCH/$slug.horig"
	f="$SCRATCH/$slug.HANDOFF-NOTES.md"
	cp "$src" "$f"
	before=$(wc -l < "$f")

	bw_stamp_handoff_notes "$f" "9.9.9" "2026-08-11T12:00:00Z" "abcdef0123456789abcdef0123456789"
	rc=$?
	check "returns OK"                "[[ $rc -eq 0 ]]"
	check "banner under the H1"       "[[ \"\$(sed -n 3p '$f')\" == '<!-- BW-RELEASE-STATUS:BEGIN'* ]]"
	check "H1 still line 1"           "[[ \"\$(head -1 '$f')\" == \"\$(head -1 '$src')\" ]]"
	check "states published version"  "grep -qF '> **PUBLISHED: 9.9.9** — 2026-08-11T12:00:00Z, sha256:abcdef0123456789' '$f'"
	check "grew by exactly 8 lines"   "[[ \$(wc -l < '$f') -eq $((before+8)) ]]"

	# replace, not append
	bw_stamp_handoff_notes "$f" "9.9.10" "2026-08-11T13:00:00Z" "9999999999999999eeee"
	check "one banner only"           "[[ \$(grep -c 'BW-RELEASE-STATUS:BEGIN' '$f') -eq 1 ]]"
	check "banner shows newest"       "grep -qF '> **PUBLISHED: 9.9.10**' '$f'"
	check "old version gone"          "! grep -qF 'PUBLISHED: 9.9.9' '$f'"
	check "size stable on replace"    "[[ \$(wc -l < '$f') -eq $((before+8)) ]]"
	diff <(cat "$src") <(sed '/BW-RELEASE-STATUS:BEGIN/,/BW-RELEASE-STATUS:END/d' "$f" | sed '2{/^$/d}') > "$SCRATCH/$slug.hdiff"
	check "prose byte-identical"      "[[ ! -s '$SCRATCH/$slug.hdiff' ]]"
done

# ------------------------------------------------------------------- edge cases
hdr "edge cases"
bw_stamp_session_log "$SCRATCH/does-not-exist.md" 1.0.0 t sha; rc=$?
check "absent file returns SKIP(3)"  "[[ $rc -eq 3 ]]"
bw_stamp_handoff_notes "$SCRATCH/nope.md" 1.0.0 t sha; rc=$?
check "absent handoff returns SKIP"  "[[ $rc -eq 3 ]]"

# no horizontal rule, no fenced format block: falls back to the first '## ' heading
printf '# Log\n\nIntro.\n\n## 2026-01-01 — a\n\nbody\n' > "$SCRATCH/norule.md"
bw_stamp_session_log "$SCRATCH/norule.md" 1.0.0 "2026-01-02T00:00:00Z" "ff00"
check "no-rule: ledger before entry" "[[ \$(grep -n '^## Releases' '$SCRATCH/norule.md' | cut -d: -f1) -lt \$(grep -n '^## 2026-01-01' '$SCRATCH/norule.md' | cut -d: -f1) ]]"

# a setext H2 (text then ---) must not be split down the middle
printf '# Log\nSubtitle\n---\n\n## 2026-01-01 — a\n' > "$SCRATCH/setext.md"
bw_stamp_session_log "$SCRATCH/setext.md" 1.0.0 "2026-01-02T00:00:00Z" "ff00"
check "setext heading intact"        "[[ \"\$(sed -n '2,3p' '$SCRATCH/setext.md')\" == \$'Subtitle\n---' ]]"

# a '---' inside a fenced block must not be mistaken for the preamble rule
printf '# Log\n\n## Format\n\n```\n\n---\n## YYYY-MM-DD\n```\n\n---\n\n## 2026-01-01 — a\n' > "$SCRATCH/fence.md"
bw_stamp_session_log "$SCRATCH/fence.md" 1.0.0 "2026-01-02T00:00:00Z" "ff00"
led=$(grep -n '^## Releases' "$SCRATCH/fence.md" | cut -d: -f1)
lastfence=$(grep -n '^```' "$SCRATCH/fence.md" | tail -1 | cut -d: -f1)
check "fence not entered"            "[[ $led -gt $lastfence ]]"
check "fenced example intact"        "[[ \$(grep -c '^## YYYY-MM-DD' '$SCRATCH/fence.md') -eq 1 ]]"

# handoff with no H1 on line 1 → banner goes to the very top, nothing lost
printf 'no title here\n\nbody\n' > "$SCRATCH/noh1.md"
bw_stamp_handoff_notes "$SCRATCH/noh1.md" 1.0.0 "2026-01-02T00:00:00Z" "ff00"
check "no-H1: banner first"          "[[ \"\$(head -1 '$SCRATCH/noh1.md')\" == '<!-- BW-RELEASE-STATUS:BEGIN'* ]]"
check "no-H1: body preserved"        "grep -qx 'no title here' '$SCRATCH/noh1.md' && grep -qx 'body' '$SCRATCH/noh1.md'"

# a read-only file must fail cleanly and leave the original untouched
virgin_copy "$PLUGINS/bw-interlink/docs/SESSION-LOG.md" "$SCRATCH/ro.md"; chmod 444 "$SCRATCH/ro.md"
sum_before=$(sha256sum < "$SCRATCH/ro.md")
bw_stamp_session_log "$SCRATCH/ro.md" 1.0.0 "2026-01-02T00:00:00Z" "ff00"; rc=$?
check "read-only returns FAIL(1)"    "[[ $rc -eq 1 ]]"
check "read-only file unchanged"     "[[ \"\$(sha256sum < '$SCRATCH/ro.md')\" == '$sum_before' ]]"
chmod 644 "$SCRATCH/ro.md"

# no stray temp files left beside the docs
check "no droppings in scratch"      "[[ -z \"\$(find '$SCRATCH' -name '*.bw-stamp*')\" ]]"
check "no droppings in /tmp"         "[[ -z \"\$(find /tmp -maxdepth 1 -name 'bw-stamp-*' 2>/dev/null)\" ]]"

hdr "incremental: stamping a doc the backfill already wrote"
for slug in bw-lead-ai bw-dev; do
	live="$PLUGINS/$slug/docs/SESSION-LOG.md"
	if grep -qF 'BW-RELEASES:BEGIN' "$live"; then
		f="$SCRATCH/$slug.live.md"; cp "$live" "$f"
		before_lines=$(wc -l < "$f"); before_ver=$(grep -c '^> RELEASED' "$f")
		bw_stamp_session_log "$f" "99.0.0" "2026-12-31T00:00:00Z" "cafe0123456789abcdef"
		check "$slug: reused existing block"  "[[ \$(grep -c 'BW-RELEASES:BEGIN' '$f') -eq 1 ]]"
		check "$slug: exactly one line added" "[[ \$(wc -l < '$f') -eq $((before_lines+1)) ]]"
		check "$slug: version count +1"       "[[ \$(grep -c '^> RELEASED' '$f') -eq $((before_ver+1)) ]]"
		check "$slug: newest on top"          "[[ \"\$(grep -m1 '^> RELEASED' '$f')\" == '> RELEASED 99.0.0 '* ]]"
		check "$slug: prior ledger intact"    "[[ \$(grep -c '^> RELEASED' '$f') -eq $((before_ver+1)) ]]"
	else
		bad "$slug: expected a backfilled ledger to test against"
	fi
done

printf '\n\033[1m%d passed, %d failed\033[0m\n' "$PASS" "$FAIL"
[[ $FAIL -eq 0 ]]
