#!/bin/sh
# ATDD pre-commit hook — blocks commits on main/master and unregistered branches.
# Installed by `atdd init`. Bypasses require CI=true.

set -e

# --- Resolve current branch ---
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "")

# Allow: detached HEAD (CI)
if [ -z "$BRANCH" ]; then
    exit 0
fi

# --- Block all direct commits on main/master ---
case "$BRANCH" in
    main|master)
        # Allow: CI-only env bypass
        if [ "${CI:-}" = "true" ] && [ "${ATDD_ALLOW_MAIN_COMMIT:-0}" = "1" ]; then
            exit 0
        fi
        cat >&2 <<EOF

ATDD: Commit blocked — you are on $BRANCH.

NEVER edit files directly on $BRANCH.
Always create a worktree branch FIRST, before making any changes:

  atdd branch <issue-number>

If you already have uncommitted changes, recover them:

  git stash
  atdd branch <issue-number>
  cd ../<worktree-dir>
  git stash pop

CI bypass (requires CI=true):
  CI=true ATDD_ALLOW_MAIN_COMMIT=1 git commit ...

EOF
        exit 1
        ;;
esac

# --- Verify branch is registered in manifest ---
# Skip if bypass is set (e.g. bootstrap commits before atdd init)
if [ "${ATDD_SKIP_MANIFEST_CHECK:-0}" = "1" ]; then
    exit 0
fi

# Extract slug from branch name (strip prefix: feat/my-slug → my-slug)
SLUG=$(echo "$BRANCH" | sed 's|^[^/]*/||')

# Find manifest file (walk up to repo root)
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
MANIFEST="$REPO_ROOT/.atdd/manifest.yaml"

if [ -f "$MANIFEST" ]; then
    # Check if slug appears in manifest sessions
    if ! grep -q "slug:.*$SLUG" "$MANIFEST" 2>/dev/null; then
        cat >&2 <<EOF

ATDD: Branch '$BRANCH' is not registered in .atdd/manifest.yaml.

Every branch must be created through the ATDD workflow:
  1. atdd issue <slug>    # Create issue first
  2. atdd branch <N>      # Create branch from issue

This ensures issues use the standard template, are tracked in
the manifest, and have Project v2 fields set up correctly.

Bypass (bootstrap only):
  ATDD_SKIP_MANIFEST_CHECK=1 git commit ...

EOF
        exit 1
    fi
fi

# --- Staged file count warning (advisory only — never blocks) ---
STAGED=$(git diff --cached --name-only | wc -l | tr -d ' ')
MAX_STAGED=${ATDD_MAX_STAGED:-20}

if [ "$STAGED" -gt "$MAX_STAGED" ]; then
    echo "ATDD WARNING: $STAGED files staged. Consider splitting into smaller commits." >&2
    echo "Override: ATDD_MAX_STAGED=999 git commit" >&2
fi

exit 0
