#!/usr/bin/env bash
# pre-commit.guard-ssot.sample
# Opt-in Agentic OS validation hook.
# INSTALL: cp .githooks/pre-commit.guard-ssot.sample .githooks/pre-commit && chmod +x .githooks/pre-commit
#          git config core.hooksPath .githooks
# UPDATING: the installed pre-commit is a COPY (not auto-updated). After a framework
#          update, re-run the INSTALL copy to pick up hook improvements (e.g. the
#          no-python credential floor). The floor/scanner scripts themselves force-update.
#
# Validator failures block commits. Guarded SSoT receipt checks remain advisory.

set -u

ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
if [[ -z "$ROOT" ]]; then
  echo "ACX pre-commit: unable to locate the Git repository root."
  exit 1
fi

cd "$ROOT" || exit 1

# Credential pre-screen (issue #225): block secrets BEFORE they enter object history
# — CI TruffleHog only fires post-commit, by which point rotation (not deletion) is the
# remedy. Python path = scan_credentials.py (full detection); NO-PYTHON path =
# credential_floor.sh (narrow FP-free AKIA/PEM/ghp_ subset; no silent skip). Opt-in hook;
# --no-verify-bypassable; TruffleHog is the CI backstop either way.
CREDENTIAL_SCANNER=".agentcortex/tools/scan_credentials.py"
CREDENTIAL_FLOOR=".agentcortex/tools/credential_floor.sh"
CRED_PY=""
command -v python >/dev/null 2>&1 && CRED_PY=python
[[ -z "$CRED_PY" ]] && command -v python3 >/dev/null 2>&1 && CRED_PY=python3
cred_rc=0
if [[ -n "$CRED_PY" && -f "$CREDENTIAL_SCANNER" ]]; then
  "$CRED_PY" "$CREDENTIAL_SCANNER" --staged; cred_rc=$?
elif [[ -f "$CREDENTIAL_FLOOR" ]]; then
  bash "$CREDENTIAL_FLOOR" --staged; cred_rc=$?            # no-python narrow floor
else
  echo "ACX pre-commit: no credential pre-screen available on this host; CI TruffleHog backstops."
fi
if [[ "$cred_rc" -eq 1 ]]; then
  echo "ACX pre-commit: credential pattern detected in staged changes; commit blocked."
  echo "   Rotate the exposed secret, remove it from the change, then re-commit."
  exit 1
elif [[ "$cred_rc" -ne 0 ]]; then
  echo "ACX pre-commit: credential pre-screen could not run (exit $cred_rc); continuing (CI TruffleHog backstops)."
fi

GUARD_RECEIPT=".agentcortex/context/.guard_receipts"
GUARDED_PATHS=(
  ".agentcortex/context/current_state.md"
  "AGENTS.md"
  ".agent/config.yaml"
)

is_windows_git_shell() {
  case "$(uname -s 2>/dev/null || echo unknown)" in
    MINGW*|MSYS*|CYGWIN*) return 0 ;;
    *) return 1 ;;
  esac
}

run_validator() {
  if is_windows_git_shell && [[ -f ".agentcortex/bin/validate.ps1" ]]; then
    if command -v powershell >/dev/null 2>&1; then
      powershell -ExecutionPolicy Bypass -File ".agentcortex/bin/validate.ps1"
      return $?
    fi
    if command -v pwsh >/dev/null 2>&1; then
      pwsh -NoProfile -ExecutionPolicy Bypass -File ".agentcortex/bin/validate.ps1"
      return $?
    fi
  fi

  if [[ ! -f ".agentcortex/bin/validate.sh" ]]; then
    echo "ACX pre-commit: missing .agentcortex/bin/validate.sh."
    return 1
  fi

  bash ".agentcortex/bin/validate.sh"
}

echo "ACX pre-commit: running local validator..."
if ! run_validator; then
  echo "ACX pre-commit: validator failed; commit blocked."
  exit 1
fi
echo "ACX pre-commit: validator passed."

for path in "${GUARDED_PATHS[@]}"; do
  if git diff --cached --name-only | grep -qxF "$path"; then
    # Check for a recent receipt (written in last 60 minutes)
    if [[ ! -d "$GUARD_RECEIPT" ]] || ! find "$GUARD_RECEIPT" -name "*.json" -newer "$path" -mmin -60 | grep -q .; then
      echo "GUARD WARN: $path staged without a recent guard receipt."
      echo "   Run guard_context_write.py or use the /ship workflow to update SSoT."
      echo "   (Advisory only - commit not blocked)"
    fi
  fi
done

exit 0
