#!/usr/bin/env bash
# PreToolUse gate — DENY agent mutation of the SHARED main checkout.
# Incident: two agent sessions both had cwd == /home/user/Projects/overdeck (the main
# checkout). One ran `git restore`/`git checkout --`, which acts on the whole working
# tree and silently destroyed the other session's uncommitted edits.
#
# Scope: only repos that have opted into worktree isolation (a <main_root>/.worktrees
# directory, created by `od-worktree add`) are enforced. Repos with no such convention
# are left alone — this must never block a single-checkout project.
#
# Blocks, when the effective location is the main checkout (not a path under
# <main_root>/.worktrees/<slug>):
#   - Edit/Write to any file_path resolving inside the main checkout tree
#   - Bash: git restore | git checkout -- <path> | git checkout . |
#           git stash (push/pop/drop/clear) | git clean -f* | git reset --hard
# Read-only ops (status/log/diff/show/grep/read, any non-matching Bash) pass through.
set -euo pipefail

LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/lib" && pwd)"
# shellcheck source=lib/worktree-guard-lib.sh
source "$LIB_DIR/worktree-guard-lib.sh"

INPUT=$(cat)
TOOL=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty')
CWD=$(printf '%s' "$INPUT" | jq -r '.cwd // empty')
[[ -z "$TOOL" || -z "$CWD" ]] && exit 0

deny() {
  jq -n --arg r "$1" '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: $r
    }
  }'
  exit 0
}

FIX='Create/claim a worktree and work there: `~/.claude/bin/od-worktree add <slug>`, then cd into /home/user/Projects/overdeck/.worktrees/<slug>.'

MAIN_ROOT=$(wt_main_root "$CWD") || exit 0
[[ -d "$MAIN_ROOT/.worktrees" ]] || exit 0

case "$TOOL" in
  Edit|Write)
    TARGET=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty')
    [[ -z "$TARGET" ]] && exit 0
    [[ "$TARGET" != /* ]] && TARGET="$CWD/$TARGET"
    if wt_is_main_checkout_path "$TARGET" "$MAIN_ROOT"; then
      deny "main-checkout-guard: writing to $TARGET mutates the SHARED main checkout ($MAIN_ROOT) — another session's uncommitted work lives there too. $FIX"
    fi
    ;;
  Bash)
    CMD=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty')
    [[ -z "$CMD" ]] && exit 0
    wt_has_destructive_git "$CMD" || exit 0

    # Candidate execution dirs: the tool's cwd, plus any `cd <dir>` target in the
    # command — a leading `cd <main_root> && git restore .` from a worktree session
    # must be caught too, not just a bare invocation already sitting in the main root.
    IS_MAIN=0
    if wt_is_main_checkout_path "$CWD" "$MAIN_ROOT"; then
      IS_MAIN=1
    else
      while IFS= read -r target; do
        [[ -z "$target" ]] && continue
        [[ "$target" != /* ]] && target="$CWD/$target"
        if wt_is_main_checkout_path "$target" "$MAIN_ROOT"; then
          IS_MAIN=1
          break
        fi
      done < <(wt_cd_targets "$CMD")
    fi
    [[ "$IS_MAIN" -eq 1 ]] || exit 0
    deny "main-checkout-guard: this git command discards/overwrites working-tree state in the SHARED main checkout ($MAIN_ROOT) — it can silently destroy another session's uncommitted edits. $FIX"
    ;;
esac

exit 0
