#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# cleanup.sh — roll back a bootstrap install (the inverse of bootstrap.sh).
#
# Run from the kit folder, pointing at the repo you bootstrapped:
#   ./cleanup.sh [TARGET_REPO_DIR]            # DRY RUN — shows what it would do
#   ./cleanup.sh [TARGET_REPO_DIR] --apply    # actually perform the rollback
#
# SAFE BY DESIGN: it only removes files that are byte-identical to the kit's pristine
# output (untouched bootstrap files). Anything you changed — a filled-in CLAUDE.md,
# edited registries, your own agents — is KEPT and reported. If bootstrap made a `.bak`
# (a `--force` overwrite), the original is RESTORED from it. Empty directories bootstrap
# created are removed; directories that still hold your files are left in place.
# ─────────────────────────────────────────────────────────────────────────────
set -uo pipefail

KIT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TARGET="."; APPLY=0
for a in "$@"; do
  case "$a" in
    --apply) APPLY=1 ;;
    -h|--help) sed -n '2,18p' "$0"; exit 0 ;;
    *) TARGET="$a" ;;
  esac
done
TARGET="$(cd "$TARGET" && pwd)"

mode=$([[ $APPLY -eq 1 ]] && echo APPLY || echo "DRY RUN")
echo "Rolling back the Constitution kit  [$mode]"
echo "  kit:    $KIT_DIR"
echo "  target: $TARGET"
echo

removed=0; restored=0; kept=0

handle() { # handle <kit_src | -> <dest_rel>
  local src="$1" dest="$2" tgt="$TARGET/$2"
  [[ -e "$tgt" ]] || return 0
  if [[ "$src" != "-" && -f "$src" ]] && cmp -s "$src" "$tgt"; then
    if [[ -e "$tgt.bak" ]]; then
      echo "  restore  $dest  (from .bak)"; restored=$((restored+1))
      if [[ $APPLY -eq 1 ]]; then mv -f "$tgt.bak" "$tgt"; fi
    else
      echo "  remove   $dest"; removed=$((removed+1))
      if [[ $APPLY -eq 1 ]]; then rm -f "$tgt"; fi
    fi
  elif [[ "$src" == "-" ]]; then            # marker file (.gitkeep)
    if [[ ! -s "$tgt" ]]; then
      echo "  remove   $dest  (marker)"; removed=$((removed+1))
      if [[ $APPLY -eq 1 ]]; then rm -f "$tgt"; fi
    else
      echo "  keep     $dest  (not empty)"; kept=$((kept+1))
    fi
  else
    echo "  keep     $dest  (modified or your own — untouched)"; kept=$((kept+1))
  fi
}

for f in "$KIT_DIR"/agents/*.md;   do handle "$f" ".claude/agents/$(basename "$f")"; done
for f in "$KIT_DIR"/commands/*.md; do handle "$f" ".claude/commands/$(basename "$f")"; done
handle "$KIT_DIR/CONSTITUTION.md"                "CONSTITUTION.md"
handle "$KIT_DIR/SPECIALIZE.md"                  "SPECIALIZE.md"
handle "$KIT_DIR/SKILLS.md"                      "SKILLS.md"
handle "$KIT_DIR/PROMPT_TEMPLATES.md"            "PROMPT_TEMPLATES.md"
handle "$KIT_DIR/templates/SCREEN_REGISTRY.md"   "docs/SCREEN_REGISTRY.md"
handle "$KIT_DIR/templates/WORKFLOW_REGISTRY.md" "docs/WORKFLOW_REGISTRY.md"
handle "$KIT_DIR/templates/INTERACTION_REGISTRY.md" "docs/INTERACTION_REGISTRY.md"
handle "$KIT_DIR/templates/PROGRESS.md"          "docs/PROGRESS.md"
handle "$KIT_DIR/templates/INSIGHTS.md"          "docs/INSIGHTS.md"
handle "$KIT_DIR/templates/LESSONS.md"           "docs/LESSONS.md"
handle "$KIT_DIR/templates/DESIGN_BACKLOG.md"    "docs/DESIGN_BACKLOG.md"
handle "$KIT_DIR/templates/DESIGN_PROMPTS.md"    "docs/DESIGN_PROMPTS.md"
handle "$KIT_DIR/templates/CLAUDE.master.md"     "CLAUDE.md"
handle "$KIT_DIR/templates/settings.json"        ".claude/settings.json"
handle "$KIT_DIR/templates/verify.sh"            ".claude/hooks/verify.sh"
handle "$KIT_DIR/templates/verify.ps1"           ".claude/hooks/verify.ps1"
# preflight gate harness
while IFS= read -r -d '' f; do
  rel="${f#$KIT_DIR/scripts/preflight/}"
  handle "$f" ".claude/hooks/preflight/$rel"
done < <(find "$KIT_DIR/scripts/preflight" -type f -print0)
# opt-in hooks + example settings
handle "$KIT_DIR/templates/oncodeedit.ps1"                  ".claude/hooks/oncodeedit.ps1"
handle "$KIT_DIR/templates/notify.ps1"                      ".claude/hooks/notify.ps1"
handle "$KIT_DIR/templates/settings.preflight.example.json" ".claude/settings.preflight.example.json"
# session ledger
handle "$KIT_DIR/templates/session-ledger.js"               ".claude/hooks/session-ledger.js"
handle "$KIT_DIR/templates/session-hook.ps1"                ".claude/hooks/session-hook.ps1"
handle "$KIT_DIR/templates/session-hook.sh"                 ".claude/hooks/session-hook.sh"
handle "$KIT_DIR/templates/settings.session.example.json"   ".claude/settings.session.example.json"
handle "$KIT_DIR/templates/SESSION_SETUP.md"                "docs/SESSION_SETUP.md"
handle "$KIT_DIR/tools/SessionLedger.Tests.ps1"             ".claude/tools/SessionLedger.Tests.ps1"
# wave scheduler tools
handle "$KIT_DIR/tools/Compute-WaveSchedule.ps1"     ".claude/tools/Compute-WaveSchedule.ps1"
handle "$KIT_DIR/tools/Schedule.Tests.ps1"           ".claude/tools/Schedule.Tests.ps1"
handle "$KIT_DIR/tools/Verify-WaveDisjoint.ps1"       ".claude/tools/Verify-WaveDisjoint.ps1"
handle "$KIT_DIR/tools/Verify-WaveDisjoint.Tests.ps1" ".claude/tools/Verify-WaveDisjoint.Tests.ps1"
handle "$KIT_DIR/tools/RenderFilter.Tests.ps1"        ".claude/tools/RenderFilter.Tests.ps1"
handle "$KIT_DIR/tools/spans.fixture.json"           ".claude/tools/spans.fixture.json"
handle "$KIT_DIR/tools/PARALLELISM.md"               ".claude/tools/PARALLELISM.md"
# notify setup doc
handle "$KIT_DIR/templates/NOTIFY_SETUP.md"      "docs/NOTIFY_SETUP.md"
# reports index
handle "$KIT_DIR/templates/reports-README.md"    "docs/reports/README.md"
# optional code-discovery graph ignore file
handle "$KIT_DIR/templates/cbmignore"            ".cbmignore"
handle "$KIT_DIR/templates/SKILL.template.md"    ".claude/skills/SKILL.template.md"
handle "$KIT_DIR/tools/progress.ps1"             ".claude/tools/progress.ps1"
# workflow scripts shipped with the kit
if [[ -d "$KIT_DIR/workflows" ]]; then
  for wf in "$KIT_DIR"/workflows/*.js; do [[ -e "$wf" ]] && handle "$wf" ".claude/workflows/$(basename "$wf")"; done
fi
handle "-" "docs/APPROVAL_INBOX/.gitkeep"
handle "-" ".claude/skills/.gitkeep"
# project skills shipped with the kit
if [[ -d "$KIT_DIR/skills" ]]; then
  for sd in "$KIT_DIR"/skills/*/; do
    [[ -d "$sd" ]] || continue
    sname="$(basename "$sd")"
    for sf in "$sd"*.md; do [[ -e "$sf" ]] && handle "$sf" ".claude/skills/$sname/$(basename "$sf")"; done
  done
fi

# remove now-empty skill subdirs first
for sd in "$TARGET"/.claude/skills/*/; do
  if [[ -d "$sd" && -z "$(ls -A "$sd" 2>/dev/null)" ]]; then
    echo "  rmdir    .claude/skills/$(basename "$sd")  (empty)"
    if [[ $APPLY -eq 1 ]]; then rmdir "$sd"; fi
  fi
done
# remove now-empty directories bootstrap created (deepest first)
for d in docs/APPROVAL_INBOX docs/design-system docs/reports docs/journal docs \
         .claude/tools .claude/workflows .claude/skills \
         .claude/hooks/preflight/dotnet-pack/selftests/Integration \
         .claude/hooks/preflight/dotnet-pack/selftests \
         .claude/hooks/preflight/dotnet-pack \
         .claude/hooks/preflight/selftests/_v_selftest \
         .claude/hooks/preflight/selftests \
         .claude/hooks/preflight \
         .claude/hooks .claude/commands .claude/agents .claude; do
  dir="$TARGET/$d"
  if [[ -d "$dir" && -z "$(ls -A "$dir" 2>/dev/null)" ]]; then
    echo "  rmdir    $d  (empty)"
    if [[ $APPLY -eq 1 ]]; then rmdir "$dir"; fi
  fi
done

echo
echo "Summary: $removed to remove, $restored to restore, $kept kept."
if [[ $APPLY -eq 0 ]]; then
  echo "Dry run — re-run with --apply to perform the rollback."
else
  echo "Rollback complete."
fi
