#!/usr/bin/env bash
# core/hooks/pre-push — PhaseOps core pre-push hook
#
# Verifies that .planning/SESSION_HANDOFF.md top-fragment agrees with
# .phaseops/state/active.json on `branch` and `current_slice` (per the
# SESSION_HANDOFF_FRAGMENT contract), and that .phaseops/audit.jsonl is
# git-tracked. Hard-stop on mismatch; warn-only on missing surfaces.
#
# Escape hatch: PHASEOPS_NO_PREPUSH=1 git push ...

set -euo pipefail

if [ "${PHASEOPS_NO_PREPUSH:-0}" = "1" ]; then
  exit 0
fi

current_branch=$(git rev-parse --abbrev-ref HEAD)

HANDOFF_FILE=".planning/SESSION_HANDOFF.md"
STATE_FILE=".phaseops/state/active.json"
AUDIT_FILE=".phaseops/audit.jsonl"

# Branch + slice parity between handoff fragment and active state.
if [ -f "$HANDOFF_FILE" ] && [ -f "$STATE_FILE" ]; then
  # Handoff fragment uses inline bold-label markdown:
  #   - **Branch**: `main`
  #   - **Workflow**: `implement` (A-1 ...) — current slice id is bracketed
  handoff_branch=$(awk -F'`' '/\*\*Branch\*\*/ {print $2; exit}' "$HANDOFF_FILE")
  # Portable: match() in BSD awk doesn't return groups, so use sed for capture.
  handoff_slice=$(grep -m1 '\*\*Workflow\*\*' "$HANDOFF_FILE" 2>/dev/null \
    | sed -nE 's/.*\(([A-Z]+-[0-9A-Za-z-]+).*/\1/p')

  state_branch=$(awk -F'"' '/"branch"[[:space:]]*:/ {print $4; exit}' "$STATE_FILE")
  state_slice=$(awk -F'"' '/"current_slice"[[:space:]]*:/ {print $4; exit}' "$STATE_FILE")

  if [ -n "$handoff_branch" ] && [ -n "$state_branch" ] && \
     [ "$handoff_branch" != "$state_branch" ]; then
    echo "ERROR: SESSION_HANDOFF.md branch ('$handoff_branch') != active.json branch ('$state_branch')" >&2
    echo "Reconcile .planning/SESSION_HANDOFF.md and .phaseops/state/active.json before pushing." >&2
    exit 1
  fi

  if [ -n "$handoff_slice" ] && [ -n "$state_slice" ] && \
     [ "$handoff_slice" != "$state_slice" ]; then
    echo "ERROR: SESSION_HANDOFF.md current slice ('$handoff_slice') != active.json current_slice ('$state_slice')" >&2
    echo "Reconcile .planning/SESSION_HANDOFF.md and .phaseops/state/active.json before pushing." >&2
    exit 1
  fi

  # Hard-stop: current branch must match what the handoff says we're on.
  if [ -n "$handoff_branch" ] && [ "$current_branch" != "$handoff_branch" ]; then
    echo "ERROR: current branch '$current_branch' does not match SESSION_HANDOFF.md branch '$handoff_branch'" >&2
    exit 1
  fi
elif [ -f "$STATE_FILE" ] && [ ! -f "$HANDOFF_FILE" ]; then
  echo "WARN: active state present but $HANDOFF_FILE is missing — handoff parity unchecked" >&2
fi

# Audit log must be git-tracked (the audit trail is the durable record).
if [ -f "$AUDIT_FILE" ]; then
  if ! git ls-files --error-unmatch "$AUDIT_FILE" >/dev/null 2>&1; then
    echo "ERROR: $AUDIT_FILE exists but is not git-tracked. Add it: git add $AUDIT_FILE" >&2
    exit 1
  fi
fi

# Adapter hooks (if any) are appended below by `phaseops init`.
# ---- ADAPTER HOOKS APPENDED BELOW ----
exit 0
