#!/usr/bin/env bash
# Hook pre-push versionné (git config core.hooksPath .githooks).
# 1. Refuse une poussée dont les lignes ajoutées contiennent un terme privé ; la liste vit
#    dans .git/info/private-terms (un terme par ligne, # pour un commentaire), jamais suivie.
# 2. Lance les tests touchés : fichiers de test modifiés, et tests/test_<module>*.py pour
#    chaque module modifié.
set -euo pipefail

root=$(git rev-parse --show-toplevel)
terms="$(git rev-parse --git-dir)/info/private-terms"
zero=0000000000000000000000000000000000000000
changed=""
status=0

while read -r _local_ref local_sha _remote_ref remote_sha; do
    [ "$local_sha" = "$zero" ] && continue  # suppression de branche
    if [ "$remote_sha" = "$zero" ]; then
        base=$(git merge-base "$local_sha" origin/main 2>/dev/null || git rev-list --max-parents=0 "$local_sha" | tail -1)
    else
        base=$remote_sha
    fi
    if [ -s "$terms" ]; then
        patterns=$(grep -v '^[[:space:]]*\(#\|$\)' "$terms" || true)
        if [ -n "$patterns" ]; then
            hits=$(git diff --unified=0 "$base" "$local_sha" | grep '^+' | grep -v '^+++' | grep -iF -o -f <(printf '%s\n' "$patterns") | sort -u || true)
            if [ -n "$hits" ]; then
                echo "pre-push : terme(s) privé(s) dans les lignes poussées :" >&2
                printf '%s\n' "$hits" | sed 's/^/  /' >&2
                status=1
            fi
        fi
    fi
    changed="$changed $(git diff --name-only "$base" "$local_sha")"
done

[ "$status" -ne 0 ] && { echo "pre-push : poussée refusée." >&2; exit 1; }

tests=""
for f in $changed; do
    case "$f" in
        tests/test_*.py) [ -f "$root/$f" ] && tests="$tests $f" ;;
        accesspath/*.py|accesspath/*/*.py)
            mod=$(basename "$f" .py)
            for t in "$root"/tests/test_"$mod"*.py; do [ -f "$t" ] && tests="$tests tests/$(basename "$t")"; done ;;
    esac
done
tests=$(printf '%s\n' $tests | sort -u | tr '\n' ' ')
if [ -n "${tests// /}" ]; then
    py="$root/.venv/bin/python"; [ -x "$py" ] || py=python3
    echo "pre-push : tests touchés :$tests" >&2
    (cd "$root" && "$py" -m pytest -q -x -p no:cacheprovider -m "not network" $tests) || { echo "pre-push : tests en échec, poussée refusée." >&2; exit 1; }
fi
exit 0
