#!/bin/sh
# Pre-commit hook: lint-staged (JS+CSS+PHP) with PHP-native fallback.
# If node_modules is missing, fall back to running phpcs/phpcbf directly
# so PHP indentation errors are caught even without a full npm install.

# --- Guard: block dev-dependency references in committed vendor manifests ---
# Dev packages (phpunit, phpstan, etc.) are gitignored under vendor/ but the
# Jetpack autoloader manifests are tracked. If someone runs `composer install`
# or `composer dump-autoload` (without --no-dev) and stages the result,
# WordPress Playground and any git-clone-based install will crash.
VENDOR_MANIFESTS=$(git diff --cached --name-only --diff-filter=ACM | grep -E '^vendor/composer/(jetpack_autoload_|autoload_(classmap|files|namespaces|psr4|static)\.php|installed\.php)' || true)
if [ -n "$VENDOR_MANIFESTS" ]; then
	# Gitignored dev vendor dirs — must not appear in committed autoloader manifests.
	# Note: installed.json is excluded because upstream packages legitimately list
	# dev dependencies in their own require-dev metadata (e.g., jetpack-autoloader
	# lists yoast/phpunit-polyfills). Those are just metadata, not installed paths.
	DEV_PATHS="myclabs/\|phpunit/\|phpstan/\|phpcsstandards/\|squizlabs/\|sebastian/\|nikic/\|phar-io/\|doctrine/\|dealerdirect/\|phpcompatibility/\|php-stubs/\|szepeviktor/\|theseer/\|wp-coding-standards/\|yoast/"
	for manifest in $VENDOR_MANIFESTS; do
		if git show ":$manifest" 2>/dev/null | grep -q "$DEV_PATHS"; then
			echo ""
			echo "pre-commit: BLOCKED — staged $manifest contains dev-dependency references."
			echo "These packages are gitignored and will crash WordPress Playground."
			echo ""
			echo "Fix: run 'composer install --no-dev', then 'git add vendor/', then commit."
			echo "     (run 'composer install' afterwards to restore dev deps locally)"
			echo ""
			exit 1
		fi
	done
fi

# --- Ensure PHP tooling is available ---
if [ ! -x "vendor/bin/phpcs" ]; then
	if command -v composer >/dev/null 2>&1; then
		echo "pre-commit: vendor/bin/phpcs not found — running composer install..."
		composer install --quiet
	else
		echo "pre-commit: vendor/bin/phpcs not found and composer is not installed."
		echo "Install Composer (https://getcomposer.org) and re-run your commit."
		exit 1
	fi
fi

if command -v npx >/dev/null 2>&1 && [ -d "node_modules/.bin" ]; then
	npx lint-staged
else
	# Fallback: run phpcs/phpcbf on staged PHP files without lint-staged
	STAGED_PHP=$(git diff --cached --name-only --diff-filter=ACM | grep '\.php$' || true)
	[ -z "$STAGED_PHP" ] && exit 0

	if [ ! -x "vendor/bin/phpcs" ]; then
		echo "pre-commit: vendor/bin/phpcs not found — run 'composer install' first."
		exit 1
	fi

	# Detect partially staged files (unstaged changes exist for the same file)
	PARTIALLY_STAGED=""
	for file in $STAGED_PHP; do
		if git diff --name-only -- "$file" | grep -q .; then
			PARTIALLY_STAGED="$PARTIALLY_STAGED $file"
		fi
	done

	if [ -n "$PARTIALLY_STAGED" ]; then
		# Cannot safely auto-fix — phpcbf would modify the working copy
		# and re-staging would include unstaged hunks. Just check.
		echo "pre-commit: partially staged PHP files detected, skipping auto-fix:"
		echo "$PARTIALLY_STAGED"
		# shellcheck disable=SC2086
		vendor/bin/phpcs $STAGED_PHP
	else
		# Auto-fix, re-stage, then verify
		# shellcheck disable=SC2086
		vendor/bin/phpcbf $STAGED_PHP 2>/dev/null || true
		# shellcheck disable=SC2086
		git add $STAGED_PHP
		# shellcheck disable=SC2086
		vendor/bin/phpcs $STAGED_PHP
	fi
fi
