#!/usr/bin/env bash
# Validate fact_id references in content YAML against canonical knowledge catalogs.
# Part of pre-commit checks (ticket #393). Grep-based, targets <2s runtime.
#
# Modes:
#   Advisory — when knowledge catalogs have no fact definitions yet (exit 0)
#   Enforcing — when catalogs are populated; fails on unknown fact_ids (exit 1)
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"

KNOWLEDGE_DIR="$REPO_ROOT/content/global/knowledge"
CONTENT_DIR="$REPO_ROOT/content/campaigns"

# --- Extract canonical fact_ids from knowledge catalogs ---
# Matches YAML lines like:  fact_id: some_value  or  fact_id: "some_value"
# Excludes entity-attributes.yaml (different schema: attribute keys, not fact_ids)
CANONICAL_IDS=""
if [ -d "$KNOWLEDGE_DIR" ]; then
    CANONICAL_IDS=$(
        grep -rh 'fact_id:\s*' "$KNOWLEDGE_DIR" \
            --include='*.yaml' \
            --exclude='entity-attributes.yaml' \
        | grep -v '^\s*#' \
        | sed 's/.*fact_id:\s*//' \
        | sed 's/\s*#.*//' \
        | sed "s/^[\"']\(.*\)[\"']$/\1/" \
        | sed 's/[[:space:]]*$//' \
        | sort -u \
        || true
    )
fi

CANONICAL_COUNT=$(echo "$CANONICAL_IDS" | grep -c '\S' || true)

# --- Extract referenced fact_ids from campaign content ---
# Covers monologue prerequisites.facts[].fact_id and dialogue knowledge_grant.fact_id
REFERENCED=""
if [ -d "$CONTENT_DIR" ]; then
    REFERENCED=$(
        grep -rh 'fact_id:\s*' "$CONTENT_DIR" \
            --include='*.yaml' \
        | grep -v '^\s*#' \
        | sed 's/.*fact_id:\s*//' \
        | sed 's/\s*#.*//' \
        | sed "s/^[\"']\(.*\)[\"']$/\1/" \
        | sed 's/[[:space:]]*$//' \
        || true
    )
fi

REFERENCED_UNIQUE=$(echo "$REFERENCED" | sort -u | grep '\S' || true)
REF_COUNT=$(echo "$REFERENCED_UNIQUE" | grep -c '\S' || true)

# --- Compare ---
if [ "$CANONICAL_COUNT" -eq 0 ]; then
    echo "check-fact-ids: WARNING — no canonical fact_ids in knowledge catalogs"
    echo "  Catalogs not yet populated. Check is advisory only."
    if [ "$REF_COUNT" -gt 0 ]; then
        echo "  $REF_COUNT unique fact_ids referenced in content:"
        echo "$REFERENCED_UNIQUE" | sed 's/^/    /'
    fi
    exit 0
fi

# Enforcing mode: catalogs have definitions
ERRORS=0
while IFS= read -r ref_id; do
    [ -z "$ref_id" ] && continue
    if ! echo "$CANONICAL_IDS" | grep -qxF "$ref_id"; then
        echo "ERROR: unknown fact_id '$ref_id' — not in knowledge catalogs"
        grep -rn "fact_id:\s*$ref_id" "$CONTENT_DIR" --include='*.yaml' \
            | sed "s|$REPO_ROOT/||" \
            | sed 's/^/  /'
        ERRORS=$((ERRORS + 1))
    fi
done <<< "$REFERENCED_UNIQUE"

if [ "$ERRORS" -gt 0 ]; then
    echo ""
    echo "check-fact-ids: FAILED — $ERRORS unknown fact_id(s)"
    echo "  Canonical fact_ids defined in: content/global/knowledge/*.yaml"
    echo "  Run 'make check-fact-ids' to recheck."
    exit 1
fi

echo "check-fact-ids: OK — $REF_COUNT references validated against $CANONICAL_COUNT canonical facts"
exit 0
