# Disable set -e inherited from husky's sh -e wrapper.
# Git hooks run with stdout as a closed/broken pipe, causing echo to fail
# with "write error: Bad file descriptor". Under set -e this silently kills
# the entire hook. This script has explicit exit 1 calls for real failures.
set +e

# Redirect stdout to stderr so user-facing messages reach the terminal
# instead of git's closed stdout pipe.
exec 1>&2

echo "🧪 Running tests before push to ensure code quality..."
echo "💡 This prevents broken code from being pushed to GitHub."
echo ""

# Source cargo environment if available (for Rust tests)
if [ -f "$HOME/.cargo/env" ]; then
    . "$HOME/.cargo/env"
fi

# Auto-detect Docker availability and skip Docker tests if not fully functional
if ! docker buildx version >/dev/null 2>&1; then
    export SKIP_DOCKER_TESTS=true
    echo "Docker buildx not available - Docker tests will be skipped."
    echo ""
fi

# Detect if this push contains only tags (read refs from stdin)
TMP_REFS=$(mktemp 2>/dev/null || echo ./.prepush_tmp)
cat - > "$TMP_REFS"
TAGS_ONLY=true
if [ ! -s "$TMP_REFS" ]; then
    # If no stdin provided, assume this is not a tags-only push
    TAGS_ONLY=false
else
    while read -r LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA; do
        case "$LOCAL_REF" in
            refs/tags/*) : ;; # tag, ok
            *) TAGS_ONLY=false ;;
        esac
    done < "$TMP_REFS"
fi
rm -f "$TMP_REFS" 2>/dev/null || true

# Log file for verbose output (keeps hook stdout small to avoid SIGPIPE)
PRE_PUSH_LOG=$(mktemp 2>/dev/null || echo ./.pre-push-log)
cleanup_log() { rm -f "$PRE_PUSH_LOG" 2>/dev/null || true; }
trap cleanup_log EXIT

# Run linting first to catch syntax and style issues
echo "🔎 Running ESLint to catch linting issues..."
if ! pnpm run lint > "$PRE_PUSH_LOG" 2>&1; then
    echo ""
    echo "❌ Lint failed! Push blocked to prevent broken code on GitHub."
    echo "💡 Run 'pnpm run lint' to see all errors, or 'pnpm run lint:fix' for auto-fixes."
    echo ""
    tail -20 "$PRE_PUSH_LOG"
    exit 1
fi

echo "✅ Lint passed!"
echo ""

# Clean build to ensure no stale artifacts
echo "🔨 Running clean build to ensure fresh compilation..."
if ! (npm run clean > "$PRE_PUSH_LOG" 2>&1 && npm run build >> "$PRE_PUSH_LOG" 2>&1); then
    echo ""
    echo "❌ Build failed! Push blocked to prevent broken code on GitHub."
    echo "💡 Fix build errors before pushing."
    echo ""
    tail -20 "$PRE_PUSH_LOG"
    exit 1
fi

echo "✅ Build successful!"
echo ""

# Run tests (reduced suite for tag-only pushes to match release CI)
echo "🧪 Running tests (this may take a few minutes)..."
if [ "$TAGS_ONLY" = true ]; then
    echo "🔖 Tag-only push detected. Running reduced CI tests..."
    npm run test:ci-no-python > "$PRE_PUSH_LOG" 2>&1
else
    npm test > "$PRE_PUSH_LOG" 2>&1
fi

TEST_EXIT=$?

# Show the test summary (last few lines contain pass/fail counts)
grep -E "Test Files|Tests |Duration" "$PRE_PUSH_LOG" || true

if [ $TEST_EXIT -eq 0 ]; then
    echo ""
    echo "✅ All tests passed! Push will proceed."
    echo "🚀 Code quality maintained for GitHub repository."
else
    echo ""
    echo "❌ Tests failed! Push blocked to prevent broken code on GitHub."
    echo "💡 Fix failing tests or use 'git push --no-verify' for emergency pushes."
    echo "🔧 You can still make local commits for WIP - tests only run on push."
    echo ""
    echo "Failed test details:"
    grep -E "FAIL|Error|AssertionError" "$PRE_PUSH_LOG" | head -20 || true
    echo ""
    echo "Full log: $PRE_PUSH_LOG"
    # Keep log on failure so user can inspect
    trap - EXIT
    exit 1
fi

# Docstar full shadow + check (optional — runs only if docstar is installed)
if command -v docstar >/dev/null 2>&1; then
  echo "📝 Docstar: Updating shadow documentation..."
  docstar shadow . 2>/dev/null || true
  echo "🔍 Docstar: Checking documentation..."
  docstar check || true
fi
