#!/usr/bin/env bash
# =============================================================================
# upgrade-stash-cleanup.sh — clean up stale upgrade-* git stashes
# =============================================================================
# Older versions of upgrade.sh used `git stash push --include-untracked` to
# protect tenant content during pulls. When pop conflicts went unresolved,
# the stashes accumulated in `git stash list` forever — Pride Corner ended up
# with three from 2026-03-09 alone, each containing displaced tenant
# customizations that the running site no longer reflected.
#
# This script lists every `upgrade-*` stash, shows its scope, and offers to
# drop them. It does NOT auto-restore content; that's a separate decision per
# tenant. The intent is to clear the backlog so future `git stash list` is
# meaningful.
#
# Usage:
#   bash scripts/upgrade-stash-cleanup.sh          # interactive, lists + prompts
#   bash scripts/upgrade-stash-cleanup.sh --dry    # list only
#   bash scripts/upgrade-stash-cleanup.sh --yes    # drop all upgrade-* without prompt
# =============================================================================

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_DIR"

# Colors
if [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]]; then
  RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' CYAN='\033[0;36m'
  BOLD='\033[1m' NC='\033[0m'
else
  RED='' GREEN='' YELLOW='' CYAN='' BOLD='' NC=''
fi

info() { echo -e "${CYAN}[INFO]${NC} $*"; }
ok()   { echo -e "${GREEN}[ OK ]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }

DRY=false
YES=false
for arg in "$@"; do
  case "$arg" in
    --dry|--dry-run) DRY=true ;;
    --yes|-y)        YES=true ;;
    --help|-h)
      sed -n '2,/^# =====/p' "$0" | sed -n '2,/^# =====/p' | sed 's/^# //;s/^#//'
      exit 0
      ;;
  esac
done

if [[ ! -d .git ]]; then
  warn "Not a git repository — this script only applies to source installs."
  exit 0
fi

# Collect upgrade-* stash refs
mapfile -t STASHES < <(git stash list 2>/dev/null | grep -E ': (On|WIP on) [^:]+: upgrade-' || true)

if [[ ${#STASHES[@]} -eq 0 ]]; then
  ok "No upgrade-* stashes found. Nothing to clean up."
  exit 0
fi

echo ""
echo -e "${BOLD}Found ${#STASHES[@]} upgrade-* stash(es):${NC}"
echo ""
for entry in "${STASHES[@]}"; do
  REF="${entry%%:*}"
  LABEL="${entry#*: }"
  FILE_COUNT=$(git stash show "$REF" --name-only 2>/dev/null | wc -l)
  HAS_MKDOCS_YML=$(git stash show "$REF" --name-only 2>/dev/null | grep -c '^mkdocs/mkdocs\.yml$' || true)
  printf "  %-12s  %-50s  files=%-4d  mkdocs.yml=%s\n" \
    "$REF" "$LABEL" "$FILE_COUNT" "$HAS_MKDOCS_YML"
done
echo ""

if [[ "$DRY" == "true" ]]; then
  info "Dry-run: no stashes will be dropped."
  exit 0
fi

# Warn loudly if any stash holds mkdocs.yml — operator should manually review
# before dropping (tenant content might be there).
MKDOCS_STASHES=$(printf '%s\n' "${STASHES[@]}" \
  | while read -r entry; do
      REF="${entry%%:*}"
      if git stash show "$REF" --name-only 2>/dev/null | grep -q '^mkdocs/mkdocs\.yml$'; then
        echo "$REF"
      fi
    done)

if [[ -n "$MKDOCS_STASHES" ]]; then
  echo ""
  echo -e "${RED}${BOLD}⚠ WARNING:${NC} the following stashes contain ${BOLD}mkdocs/mkdocs.yml${NC}:"
  echo "$MKDOCS_STASHES" | sed 's/^/    /'
  echo ""
  echo "   These may hold tenant branding (site_name, site_url, custom theme, etc.)"
  echo "   that ISN'T reflected on disk. Before dropping, verify:"
  echo ""
  echo "     git show <stash-ref>:mkdocs/mkdocs.yml | head -10"
  echo "     diff <(git show <stash-ref>:mkdocs/mkdocs.yml) mkdocs/mkdocs.yml"
  echo ""
  echo "   If disk mkdocs.yml already has the tenant content, the stash is safe to drop."
  echo "   If disk is upstream and stash has tenant content, restore first:"
  echo "     git checkout <stash-ref> -- mkdocs/mkdocs.yml"
  echo ""
fi

if [[ "$YES" != "true" ]]; then
  echo -en "${BOLD}Drop all ${#STASHES[@]} upgrade-* stashes? [y/N] ${NC}"
  read -r CONFIRM
  case "$CONFIRM" in
    y|Y|yes|YES) ;;
    *) info "Cancelled. No stashes dropped."; exit 0 ;;
  esac
fi

# Drop in reverse order so indices stay stable
mapfile -t SORTED_REFS < <(printf '%s\n' "${STASHES[@]}" \
  | sed 's/:.*//' \
  | sort -t'{' -k2 -n -r)

for REF in "${SORTED_REFS[@]}"; do
  if git stash drop "$REF" >/dev/null 2>&1; then
    ok "Dropped $REF"
  else
    warn "Failed to drop $REF (already gone?)"
  fi
done

echo ""
ok "Cleanup complete. Remaining stashes:"
git stash list 2>/dev/null || echo "  (none)"
