#!/bin/sh
if [ -x .venv/Scripts/python.exe ]; then
  PYTHON=.venv/Scripts/python.exe
elif [ -x .venv/bin/python ]; then
  PYTHON=.venv/bin/python
elif command -v python3 >/dev/null 2>&1; then
  PYTHON=$(command -v python3)
elif command -v python >/dev/null 2>&1; then
  PYTHON=$(command -v python)
else
  echo "[ai-policy] Python interpreter not found." >&2
  exit 1
fi

# 1) AI 마커 차단
"$PYTHON" .claude/hooks/check_no_ai_markers.py --check-push || exit $?

# 2) push 범위의 변경 파일에 대응하는 테스트만 선별 실행.
#    전수 unit 은 10분+ 소요로 비현실적 (CI 가 최종 게이트). 변경 모듈 관련 테스트 통과만
#    강제해 이번 같은 유형 (predictionSignals 변경 → test_analysis_prediction 실패) 사고 차단.
REMOTE_BRANCH=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null)
# --diff-filter=d 로 삭제된 파일 제외 — stale 매칭이 pytest "file not found" 로
# 무관한 push 를 차단하는 회귀 차단.
if [ -n "$REMOTE_BRANCH" ]; then
  CHANGED_PY=$(git diff --name-only --diff-filter=d "$REMOTE_BRANCH..HEAD" -- 'src/dartlab/*.py' 'tests/test_*.py' 2>/dev/null)
else
  CHANGED_PY=$(git diff-tree --no-commit-id --name-only --diff-filter=d -r HEAD -- 'src/dartlab/*.py' 'tests/test_*.py' 2>/dev/null)
fi

if [ -n "$CHANGED_PY" ]; then
  # 관련 테스트 파일 수집:
  # 1) 직접 변경된 tests/*.py 파일
  # 2) 변경된 src/dartlab/<module>/*.py 의 모듈 키워드로 tests/test_<module>*.py 매칭
  TEST_FILES=""
  KEYWORDS=""
  for f in $CHANGED_PY; do
    case "$f" in
      tests/test_*.py)
        TEST_FILES="$TEST_FILES $f"
        ;;
      src/dartlab/*)
        # src/dartlab/analysis/financial/predictionSignals.py → keywords: analysis financial predictionSignals
        stem=$(basename "$f" .py)
        path=$(dirname "$f" | sed 's|src/dartlab/||; s|/| |g')
        KEYWORDS="$KEYWORDS $path $stem"
        ;;
    esac
  done

  # 중복 제거된 테스트 파일 목록
  TEST_FILES=$(echo "$TEST_FILES" | tr ' ' '\n' | sort -u | tr '\n' ' ')

  # 키워드 매칭으로 추가 테스트 파일 발견.
  # git ls-files 로 *tracked* 테스트만 — untracked WIP 테스트 (다른 작업의 미완성분) 가
  # push 막는 false positive 차단. push 자체는 tracked 만 보내므로 untracked 가
  # 통과시킬 의무 X. 회귀 가드는 commit 된 코드만 책임진다.
  for kw in $KEYWORDS; do
    [ -z "$kw" ] && continue
    matched=$(git ls-files "tests/test_*${kw}*" 2>/dev/null | tr '\n' ' ')
    TEST_FILES="$TEST_FILES $matched"
  done
  TEST_FILES=$(echo "$TEST_FILES" | tr ' ' '\n' | sort -u | grep -v '^$' | tr '\n' ' ')

  if [ -n "$(echo $TEST_FILES | tr -d ' ')" ]; then
    echo "[pre-push] 변경 대응 테스트 실행 중 (스킵: --no-verify):"
    for tf in $TEST_FILES; do echo "  - $tf"; done
    if command -v bash >/dev/null 2>&1 && [ -f scripts/dev/test-lock.sh ]; then
      PYTEST_CMD="bash scripts/dev/test-lock.sh"
    elif command -v uv >/dev/null 2>&1; then
      PYTEST_CMD="uv run pytest"
    elif [ -x .venv/bin/pytest ]; then
      PYTEST_CMD=".venv/bin/pytest"
    else
      PYTEST_CMD="pytest"
    fi
    $PYTEST_CMD $TEST_FILES -q --no-cov -x --no-header -m "unit or not (integration or heavy or realData or freshInstall)" 2>&1 | tail -40
    RC=${PIPESTATUS:-$?}
    # pytest exit 5 = "no tests collected" — 대량 rename 등으로 매칭 로직이 수집 실패한 경우.
    # 실제 회귀 검증은 CI 가 최종 게이트이므로 hook 에서는 false positive 로 간주하고 통과.
    if [ "$RC" != "0" ] && [ "$RC" != "5" ]; then
      echo "" >&2
      echo "[pre-push] 관련 테스트 실패 — push 차단." >&2
      echo "  수정 후 재push. 일시 우회: git push --no-verify" >&2
      exit 1
    fi
  fi
fi
