#!/bin/bash
# Universal RouteRTL Project Pre-Push Hook (RTL-P3.536)
#
# Runs the project's declared hooks.pre_push.tests before a push, so a
# multi-minute regression gate lives on push instead of on every commit
# (overloading pre_commit makes people reach for --no-verify). Reads config
# from project.yml via project_manager.py --gen-hook-config and runs each
# test through `rr sim run`.
#
# Opt-in: does nothing unless hooks.pre_push.enabled is true.
#
# Installed via core.hooksPath (`rr workspace install-hooks`). git invokes the
# sibling `pre-push`, which delegates here in a consumer context.

# git passes refspecs on stdin; we gate the whole push uniformly, so drain it
# (and don't let a closed pipe abort the hook).
cat >/dev/null 2>&1 || true

if [ ! -f "project.yml" ]; then
    exit 0
fi

# 1. Python interpreter (venv first, so the SDK lookup can probe site-packages).
if [ -f ".venv/bin/python3" ]; then
    PYTHON_CMD=".venv/bin/python3"
else
    PYTHON_CMD="python3"
fi

# 2. Locate SDK tools — mirrors project-pre-commit's resolution chain so a
#    pip-installed consumer isn't silently skipped (RTL-P2.346).
if [ -d "vendor/routertl/sdk" ]; then
    SDK_TOOLS="vendor/routertl/sdk"
elif [ -n "$ROUTERTL_ROOT" ]; then
    SDK_TOOLS="$ROUTERTL_ROOT/sdk"
elif [ -d "sdk/engine" ]; then
    SDK_TOOLS="sdk"
elif PIP_SDK=$($PYTHON_CMD -c 'import os, sdk; print(os.path.dirname(sdk.__file__))' 2>/dev/null) && [ -n "$PIP_SDK" ] && [ -d "$PIP_SDK/engine" ]; then
    SDK_TOOLS="$PIP_SDK"
else
    # No SDK anywhere. Refuse loudly if pre_push is configured (silent skip
    # would make users believe pushes were gated when they weren't); else skip.
    if grep -qE '^[[:space:]]*pre_push:' project.yml 2>/dev/null; then
        echo "" >&2
        echo "❌ RouteRTL SDK not found — cannot run hooks.pre_push tests." >&2
        echo "   pip install routertl, export ROUTERTL_ROOT, or add vendor/routertl." >&2
        if [ "$HOOK_SKIP_IF_MISSING" = "1" ]; then
            echo "   HOOK_SKIP_IF_MISSING=1 — skipping anyway." >&2
            exit 0
        fi
        exit 1
    fi
    exit 0
fi
PROJECT_MANAGER="$SDK_TOOLS/engine/project_manager.py"

# Inject SDK repo root into PYTHONPATH so project_manager + the rr CLI import.
SDK_REPO_ROOT="${SDK_TOOLS%/*}"
if [ "$SDK_REPO_ROOT" = "$SDK_TOOLS" ]; then
    SDK_REPO_ROOT="."
fi
export PYTHONPATH="$SDK_REPO_ROOT:$PYTHONPATH"

# 3. Read hook configuration.
if ! CONFIG=$($PYTHON_CMD "$PROJECT_MANAGER" project.yml --gen-hook-config); then
    echo "❌ Failed to parse project.yml. Push aborted." >&2
    exit 1
fi
eval "$CONFIG"

# 4. Opt-in gate.
if [ "$HOOK_PUSH_ENABLED" != "true" ]; then
    exit 0
fi

if [ -z "$HOOK_PUSH_TESTS" ]; then
    echo "ℹ️  hooks.pre_push.enabled but no tests configured — nothing to gate."
    exit 0
fi

# 5. Run the configured tests via the canonical entry point.
RR="$PYTHON_CMD -m sdk.cli.main"
echo "🧪 pre-push gate: running configured tests: $HOOK_PUSH_TESTS"

# Clean the sim workspace so stale artifacts can't yield a false pass.
# shellcheck disable=SC2086
$RR workspace clean --sim || true

for test in $HOOK_PUSH_TESTS; do
    SKIP_TEST=false
    for excluded in $HOOK_PUSH_EXCLUDE_TESTS; do
        if [ "$test" = "$excluded" ]; then
            echo "   ⏭️  Skipping (excluded): $test"
            SKIP_TEST=true
            break
        fi
    done
    if [ "$SKIP_TEST" = "true" ]; then
        continue
    fi

    # tests may carry dotted module names (tests.units.test_x); `rr sim run`
    # takes the bare testbench name, so strip to the last dotted segment.
    TB="${test##*.}"
    echo "   ▶ rr sim run $TB"
    # shellcheck disable=SC2086
    if ! $RR sim run "$TB"; then
        echo "❌ Test '$TB' failed. Push aborted." >&2
        echo "   To bypass: git push --no-verify" >&2
        exit 1
    fi
done

echo "✅ pre-push gate passed."
exit 0
