#!/usr/bin/env bash
# Rebuild a plugin's release ledger + banner from tools/release-history.json.
# Usage: tools/release-stamp-backfill.sh [--dry-run] [bw-<slug> ...]
#
# release.sh stamps the docs from now on, but plugins released before that got nothing,
# so their logs still end on a "Not released" line for versions that shipped months ago.
# This replays the recorded history into the same machine blocks release.sh writes.
#
# It only ever reads release-history.json and writes the marked blocks in the plugin's
# own docs/SESSION-LOG.md and docs/HANDOFF-NOTES.md. It does not touch the dist host,
# release-history.json, or one word of hand-written prose — a "not released" sentence in
# a session entry stays exactly as written, because it was true when it was written. The
# ledger above it is what tells a reader the current truth.
#
# Idempotent: a version already in the ledger is refreshed, not duplicated.
#
# Not owner-gated. It publishes nothing; it writes docs that are already group-writable
# to the plugin's own developers.

source "$(dirname "$0")/lib/common.sh"
source "$(dirname "$0")/lib/release-stamp.sh"

DRY_RUN=0
SLUGS=()
for arg in "$@"; do
	case "$arg" in
		--dry-run) DRY_RUN=1 ;;
		-h|--help) sed -n '2,4p' "$0"; exit 0 ;;
		-*)        die "Unknown option: $arg" ;;
		*)         SLUGS+=("$arg") ;;
	esac
done

[[ -f "$BW_RELEASE_HISTORY" ]] || die "No release history at ${BW_RELEASE_HISTORY}"

# Default to every slug that has ever been published AND still exists as a plugin
# (release-history.json remembers slugs that were since renamed or retired).
if (( ${#SLUGS[@]} == 0 )); then
	while IFS= read -r s; do
		if [[ -d "${BW_PLUGINS_DIR}/${s}" ]]; then
			SLUGS+=("$s")
		else
			log_warn "${s}: in release history but no plugin directory — skipped"
		fi
	done < <(jq -r '[.[].slug] | unique | .[]' "$BW_RELEASE_HISTORY")
fi

(( ${#SLUGS[@]} > 0 )) || die "Nothing to backfill"

TOTAL_STAMPED=0
for SLUG in "${SLUGS[@]}"; do
	require_slug "$SLUG"
	PLUGIN_DIR="${BW_PLUGINS_DIR}/${SLUG}"

	COUNT=$(jq --arg s "$SLUG" '[.[] | select(.slug == $s)] | length' "$BW_RELEASE_HISTORY")
	if [[ "$COUNT" == "0" ]]; then
		log_warn "${SLUG}: no publish history — skipped"
		continue
	fi

	# Work on copies under --dry-run so nothing in the repo is touched.
	TARGET_DIR="$PLUGIN_DIR"
	if (( DRY_RUN )); then
		TARGET_DIR=$(mktemp -d -t "bw-backfill-${SLUG}-XXXXXX")
		mkdir -p "${TARGET_DIR}/docs"
		for f in SESSION-LOG.md HANDOFF-NOTES.md; do
			if [[ -f "${PLUGIN_DIR}/docs/${f}" ]]; then
				cp "${PLUGIN_DIR}/docs/${f}" "${TARGET_DIR}/docs/${f}"
			fi
		done
	fi

	# Oldest first, so the newest release ends up on top of the ledger.
	while IFS=$'\t' read -r version released_at sha; do
		bw_stamp_session_log "${TARGET_DIR}/docs/SESSION-LOG.md" "$version" "$released_at" "$sha" \
			|| { [[ $? -eq $BW_STAMP_SKIP ]] || log_warn "${SLUG}: could not stamp ${version}"; }
	done < <(jq -r --arg s "$SLUG" \
		'[.[] | select(.slug == $s)] | sort_by(.released_at)[] | [.version, .released_at, .sha256] | @tsv' \
		"$BW_RELEASE_HISTORY")

	# The banner states current state only, so it takes the newest entry.
	while IFS=$'\t' read -r version released_at sha; do
		bw_stamp_handoff_notes "${TARGET_DIR}/docs/HANDOFF-NOTES.md" "$version" "$released_at" "$sha" \
			|| { [[ $? -eq $BW_STAMP_SKIP ]] || log_warn "${SLUG}: could not write handoff banner"; }
	done < <(jq -r --arg s "$SLUG" \
		'[.[] | select(.slug == $s)] | sort_by(.released_at) | last | [.version, .released_at, .sha256] | @tsv' \
		"$BW_RELEASE_HISTORY")

	LATEST=$(jq -r --arg s "$SLUG" '[.[] | select(.slug == $s)] | sort_by(.released_at) | last | .version' "$BW_RELEASE_HISTORY")

	if (( DRY_RUN )); then
		log_info "${BOLD}${SLUG}${RESET} — ${COUNT} release(s), latest ${LATEST} (dry run)"
		for f in SESSION-LOG.md HANDOFF-NOTES.md; do
			if [[ ! -f "${TARGET_DIR}/docs/${f}" ]]; then
				printf '    (no docs/%s — skipped)\n' "$f"
			elif ! diff -u "${PLUGIN_DIR}/docs/${f}" "${TARGET_DIR}/docs/${f}" > "${TARGET_DIR}/${f}.diff"; then
				sed 's/^/    /' "${TARGET_DIR}/${f}.diff"
			else
				printf '    (docs/%s already current)\n' "$f"
			fi
		done
		rm -rf "$TARGET_DIR"
	else
		log_ok "${SLUG}: ${COUNT} release(s) stamped, latest ${LATEST}"
	fi
	TOTAL_STAMPED=$((TOTAL_STAMPED + 1))
done

echo
if (( DRY_RUN )); then
	log_info "Dry run — ${TOTAL_STAMPED} plugin(s) previewed, nothing written."
else
	log_ok "${BOLD}Backfilled ${TOTAL_STAMPED} plugin(s)${RESET}"
fi
