#!/bin/bash
# ADR-002: Auto-ingest committed files into Pixeltable memory
# Installed by: scripts/install_hooks.sh
#
# This hook runs after each commit and ingests documentation files
# into the organizational knowledge base for context retrieval.
#
# Security hardened per LLM Council review:
# - Uses git diff-tree -z for safe filename handling
# - Passes data via environment variables (no shell interpolation in Python)
# - Reads from git object database (not working tree)

set -euo pipefail

PROJECT_ROOT="$(git rev-parse --show-toplevel)"
STATE_DIR="${PROJECT_ROOT}/.agent/state"
LOG_FILE="${PROJECT_ROOT}/.agent/logs/ingestion.log"

# Use project venv Python (critical for environment isolation)
PYTHON="${PROJECT_ROOT}/.venv/bin/python"
if [ ! -f "$PYTHON" ]; then
    PYTHON="python3"  # Fallback
fi

# Ensure directories exist
mkdir -p "$STATE_DIR" "$(dirname "$LOG_FILE")"

# Get commit SHA
COMMIT_SHA=$(git rev-parse HEAD)

# Get files changed in this commit using -z for null-delimited output (safe filenames)
# This handles filenames with spaces, newlines, or special characters
TEMP_FILE=$(mktemp)
git diff-tree --no-commit-id --name-only --diff-filter=AMR -r -z HEAD > "$TEMP_FILE"

# Filter to ingestible files (allowlist)
INGESTIBLE_PATTERNS="\.md$|\.txt$|\.rst$|docs/|adr/|ADR-"
EXCLUDED_PATTERNS="node_modules/|\.venv/|dist/|build/|__pycache__/"

# Additional secrets protection
SECRETS_PATTERNS="\.env|secret|\.key$|\.pem$|password|token|credential"

# Process null-delimited files and filter
FILTERED_FILE=$(mktemp)
while IFS= read -r -d '' file; do
    [ -z "$file" ] && continue

    # Check if file matches ingestible patterns
    if ! echo "$file" | grep -qE "$INGESTIBLE_PATTERNS"; then
        continue
    fi

    # Check if file matches excluded patterns
    if echo "$file" | grep -qE "$EXCLUDED_PATTERNS"; then
        continue
    fi

    # Check if file matches secrets patterns
    if echo "$file" | grep -qiE "$SECRETS_PATTERNS"; then
        echo "[post-commit] SKIPPED sensitive file: $file" >> "$LOG_FILE"
        continue
    fi

    # Write to filtered file (one per line for Python processing)
    printf '%s\n' "$file" >> "$FILTERED_FILE"
done < "$TEMP_FILE"

rm -f "$TEMP_FILE"

# Check if we have files to ingest
if [ ! -s "$FILTERED_FILE" ]; then
    rm -f "$FILTERED_FILE"
    echo "[post-commit] No ingestible files in commit, skipping."
    exit 0
fi

FILE_COUNT=$(wc -l < "$FILTERED_FILE" | tr -d ' ')
echo "[post-commit] Ingesting $FILE_COUNT files..."

# Run ingestion asynchronously to not block commit
# Pass data via environment variables (secure - no shell interpolation in Python)
(
    cd "$PROJECT_ROOT"

    # Log start
    echo "$(date -Iseconds) | COMMIT=$COMMIT_SHA | START | files=$FILE_COUNT" >> "$LOG_FILE"

    # Export variables for Python script (secure passing without interpolation)
    export INGEST_FILES_PATH="$FILTERED_FILE"
    export INGEST_COMMIT_SHA="$COMMIT_SHA"
    export INGEST_PROJECT_ROOT="$PROJECT_ROOT"

    # Run Python script that reads from environment variables
    "$PYTHON" -c '
import os
import sys

# Read from environment variables (no shell interpolation vulnerability)
files_path = os.environ.get("INGEST_FILES_PATH")
commit_sha = os.environ.get("INGEST_COMMIT_SHA")
project_root = os.environ.get("INGEST_PROJECT_ROOT")

if not all([files_path, commit_sha, project_root]):
    print("ERROR: Missing environment variables", file=sys.stderr)
    sys.exit(1)

try:
    from src.workflows.ingestion import ingest_file
    from pathlib import Path

    with open(files_path, "r") as f:
        files = [line.strip() for line in f if line.strip()]

    for file_path in files:
        result = ingest_file(
            file_path,
            commit_sha=commit_sha,
            project_root=Path(project_root)
        )
        status = "OK" if result.get("success") else result.get("reason", "FAILED")
        print(f"  {result.get(\"path\", file_path)}: {status}")

except Exception as e:
    print(f"ERROR: {e}", file=sys.stderr)
    sys.exit(1)
' >> "$LOG_FILE" 2>&1

    # Cleanup temp file
    rm -f "$FILTERED_FILE"

    # Record success
    echo "$COMMIT_SHA" > "$STATE_DIR/last_ingest_sha"
    echo "$(date -Iseconds) | COMMIT=$COMMIT_SHA | SUCCESS" >> "$LOG_FILE"
) &

echo "[post-commit] Ingestion queued. Check .agent/logs/ingestion.log for status."
