#!/usr/bin/env bash
# install_hooks.sh — install a custodian post-commit sync hook into registered repos.
#
# Usage:
#   ./install_hooks.sh --repo <slug>          # install into one repo
#   ./install_hooks.sh --all                  # install into all registered repos
#   ./install_hooks.sh --repo <slug> --remove # remove hook from one repo
#   ./install_hooks.sh --all --remove         # remove hook from all repos
#
# The hook runs `statehub fix-consistency --repo <slug>` after each commit,
# keeping the hub in sync with workplan file changes automatically. It falls
# back to the state-hub Make target when the CLI is not installed.
#
# Idempotent: the hook block is guarded by a marker comment. Running twice is safe.

set -euo pipefail

STATEHUB_DIR="$(cd "$(dirname "$0")/.." && pwd)"
API_BASE="${STATE_HUB_API:-http://127.0.0.1:8000}"
MARKER="# custodian-sync-hook"

usage() {
  echo "Usage: $0 --repo <slug> | --all [--remove]"
  exit 1
}

# ── Arg parsing ───────────────────────────────────────────────────────────────
REPO_SLUG=""
DO_ALL=false
REMOVE=false

while [[ $# -gt 0 ]]; do
  case "$1" in
    --repo)   REPO_SLUG="$2"; shift 2 ;;
    --all)    DO_ALL=true; shift ;;
    --remove) REMOVE=true; shift ;;
    -h|--help) usage ;;
    *) echo "Unknown argument: $1"; usage ;;
  esac
done

if [[ -z "$REPO_SLUG" && "$DO_ALL" == false ]]; then usage; fi

# ── Helper: resolve local path for a repo slug ───────────────────────────────
resolve_path() {
  local slug="$1"
  # Try the registered local_path first
  local api_path
  api_path=$(curl -sf "${API_BASE}/repos/${slug}" | python3 -c \
    "import json,sys; d=json.load(sys.stdin); print(d.get('local_path') or '')" 2>/dev/null || true)
  if [[ -n "$api_path" && -d "$api_path" ]]; then
    echo "$api_path"
    return
  fi
  # Fall back to convention: /home/<user>/<slug>
  local conventional="/home/$(whoami)/${slug}"
  if [[ -d "$conventional" ]]; then
    echo "$conventional"
    return
  fi
  echo ""
}

# ── Helper: install hook into one repo ───────────────────────────────────────
install_hook() {
  local slug="$1"
  local repo_path
  repo_path=$(resolve_path "$slug")
  if [[ -z "$repo_path" ]]; then
    echo "  ⚠  $slug: no local path found — skipping"
    return
  fi
  if [[ ! -d "$repo_path/.git" ]]; then
    echo "  ⚠  $slug: $repo_path is not a git repo — skipping"
    return
  fi

  local hook_file="$repo_path/.git/hooks/post-commit"
  local hook_block
  hook_block=$(cat <<BLOCK
${MARKER} — managed by custodian, do not edit this block
if curl -sf ${API_BASE}/state/health >/dev/null 2>&1; then
  if command -v statehub >/dev/null 2>&1; then
    (cd "${repo_path}" && statehub fix-consistency --repo ${slug} >/dev/null 2>&1 &)
  else
    (cd "${STATEHUB_DIR}" && make fix-consistency REPO=${slug} >/dev/null 2>&1 &)
  fi
fi
${MARKER}-end
BLOCK
)

  if [[ -f "$hook_file" ]] && grep -q "$MARKER" "$hook_file"; then
    echo "  ✓  $slug: hook already present at $hook_file"
    return
  fi

  if [[ -f "$hook_file" ]]; then
    # Prepend to existing hook
    local existing
    existing=$(cat "$hook_file")
    printf '#!/usr/bin/env bash\n%s\n\n%s\n' "$hook_block" "$existing" > "$hook_file"
  else
    printf '#!/usr/bin/env bash\n%s\n' "$hook_block" > "$hook_file"
  fi
  chmod +x "$hook_file"
  echo "  ✅ $slug: hook installed at $hook_file"
}

# ── Helper: remove hook from one repo ────────────────────────────────────────
remove_hook() {
  local slug="$1"
  local repo_path
  repo_path=$(resolve_path "$slug")
  if [[ -z "$repo_path" || ! -f "$repo_path/.git/hooks/post-commit" ]]; then
    echo "  –  $slug: no hook file found — skipping"
    return
  fi

  local hook_file="$repo_path/.git/hooks/post-commit"
  if ! grep -q "$MARKER" "$hook_file"; then
    echo "  –  $slug: custodian marker not found in hook — skipping"
    return
  fi

  # Remove the marked block (between MARKER and MARKER-end inclusive)
  python3 - "$hook_file" <<'PY'
import sys, re
path = sys.argv[1]
text = open(path).read()
cleaned = re.sub(
    r'# custodian-sync-hook.*?# custodian-sync-hook-end\n?',
    '',
    text,
    flags=re.DOTALL,
)
open(path, 'w').write(cleaned)
PY
  echo "  🗑  $slug: hook block removed from $hook_file"
}

# ── Collect repo slugs ────────────────────────────────────────────────────────
if $DO_ALL; then
  mapfile -t SLUGS < <(curl -sf "${API_BASE}/repos/" | python3 -c \
    "import json,sys; [print(r['slug']) for r in json.load(sys.stdin) if r.get('status') == 'active']")
else
  SLUGS=("$REPO_SLUG")
fi

echo "Custodian sync hook — $( $REMOVE && echo 'removing' || echo 'installing' ) for ${#SLUGS[@]} repo(s)"
for slug in "${SLUGS[@]}"; do
  if $REMOVE; then remove_hook "$slug"; else install_hook "$slug"; fi
done
echo "Done."
