#!/usr/bin/env bash
# PostToolUse hook: gate "tag de capability group obligatorio" tras crear/modificar
# funciones del registry. Issue 0086 paso 9/gate.
#
# Comportamiento:
#   - Detecta .md de funciones (functions/, python/functions/, bash/functions/,
#     frontend/functions/, cpp/functions/) modificados en los ultimos 60s.
#   - Lee frontmatter `tags:` y verifica si al menos uno coincide con un capability
#     group declarado en docs/capabilities/INDEX.md.
#   - Si NO hay match -> emite additionalContext con la lista de funciones afectadas.
#   - NUNCA bloquea. Solo warning visible.
#
# Salida JSON consumida por Claude Code:
#   { "hookSpecificOutput": { "hookEventName": "PostToolUse",
#                             "additionalContext": "..." } }

set -euo pipefail

resolve_root() {
    local d="${PWD}"
    while [ "$d" != "/" ]; do
        if [ -f "$d/registry.db" ]; then
            printf '%s' "$d"
            return 0
        fi
        d=$(dirname "$d")
    done
    return 1
}

ROOT=$(resolve_root) || exit 0
INDEX="$ROOT/docs/capabilities/INDEX.md"

# Si no existe el INDEX aun, no hay grupos definidos -> nada que verificar.
[ -f "$INDEX" ] || exit 0

# Consume stdin (sin parsear — no necesitamos session_id para este gate)
cat >/dev/null

# Solo correr si hay jq disponible
command -v jq >/dev/null 2>&1 || exit 0

# 1. Cargar lista de capability groups desde el INDEX.
#    Formato esperado en INDEX.md:  | [name](name.md) | N | descripcion |
CAP_GROUPS=$(grep -oE '\[[a-z][a-z0-9_-]*\]\([a-z][a-z0-9_-]*\.md\)' "$INDEX" \
    | sed -E 's/^\[([^]]+)\].*/\1/' \
    | sort -u)

[ -z "$CAP_GROUPS" ] && exit 0

# 2. Encontrar .md de funciones modificados en ultimos 60s.
RECENT=$(find "$ROOT/functions" "$ROOT/python/functions" "$ROOT/bash/functions" \
    "$ROOT/frontend/functions" "$ROOT/cpp/functions" \
    -maxdepth 4 -type f -name '*.md' -mmin -1 2>/dev/null || true)

[ -z "$RECENT" ] && exit 0

# 3. Para cada .md reciente: extraer tags del frontmatter, comparar con groups.
MISSING=""
while IFS= read -r mdfile; do
    [ -z "$mdfile" ] && continue
    # Extrae el bloque entre los dos `---` del inicio
    front=$(awk '/^---$/{c++; next} c==1 {print} c>=2 {exit}' "$mdfile" 2>/dev/null || true)
    [ -z "$front" ] && continue

    # tags: [a, b, c]  o  tags:\n  - a\n  - b
    tags_inline=$( { printf '%s\n' "$front" | grep -E '^tags:[[:space:]]*\[' | head -1 \
        | sed -E 's/^tags:[[:space:]]*\[(.*)\].*$/\1/' \
        | tr ',' '\n' | sed -E 's/^[[:space:]"]+|[[:space:]"]+$//g'; } || true )

    tags_block=$( { printf '%s\n' "$front" | awk '
        /^tags:[[:space:]]*$/ {intag=1; next}
        intag && /^[[:space:]]*-[[:space:]]/ {sub(/^[[:space:]]*-[[:space:]]*/, ""); print; next}
        intag && !/^[[:space:]]/ {intag=0}
    ' | sed -E 's/^[[:space:]"]+|[[:space:]"]+$//g'; } || true )

    tags=$( { printf '%s\n%s\n' "$tags_inline" "$tags_block" | grep -v '^$'; } || true )

    matched=0
    while IFS= read -r g; do
        [ -z "$g" ] && continue
        if printf '%s\n' "$tags" | grep -qx "$g"; then
            matched=1
            break
        fi
    done <<< "$CAP_GROUPS"

    if [ "$matched" -eq 0 ]; then
        rel="${mdfile#$ROOT/}"
        MISSING="${MISSING}${rel}\n"
    fi
done <<< "$RECENT"

# 4. Si hay funciones sin tag de grupo, emitir aviso.
if [ -n "$MISSING" ]; then
    CAP_GROUPS_CSV=$(printf '%s' "$CAP_GROUPS" | tr '\n' ',' | sed 's/,$//')
    WARN="CAPABILITY-GAP (issue 0086): funcion(es) recien tocada(s) sin tag de capability group: $(printf '%b' "$MISSING" | tr '\n' ' ')"
    WARN+="| Grupos disponibles: ${CAP_GROUPS_CSV}. Anade al menos uno al frontmatter \`tags:\` y corre \`./fn index\`. Si la funcion no encaja en ningun grupo existente, considera crear grupo nuevo (>=3 funciones) o dejarla con tag plano (no de grupo)."
    jq -n --arg ctx "$WARN" '{
      hookSpecificOutput: {
        hookEventName: "PostToolUse",
        additionalContext: $ctx
      }
    }'
fi

exit 0
