#!/usr/bin/env bash
# Scan a plugin for debug/dev cruft that shouldn't ship.
# Fails (exit 1) on error-severity findings, warns (exit 2) otherwise.
# Usage: tools/cleanup-scan.sh bw-<slug>

source "$(dirname "$0")/lib/common.sh"

SLUG="${1:-}"
require_slug "$SLUG"

PLUGIN_DIR="${BW_PLUGINS_DIR}/${SLUG}"
ALLOWLIST="${PLUGIN_DIR}/.cleanup-allowlist"
ERRORS=0
WARNINGS=0

# Files to skip entirely (these never ship, so cruft in them doesn't matter).
SKIP_DIRS='/vendor/|/docs/|/tests/|/node_modules/|/\.git/'

is_allowlisted() {
	local pat="$1" loc="$2"
	[[ -f "$ALLOWLIST" ]] || return 1
	grep -q -F "${pat} ${loc}" "$ALLOWLIST" 2>/dev/null
}

scan_pattern() {
	local severity="$1" pattern="$2" label="$3" include="${4:-*.php|*.js}"
	local findings
	findings=$(grep -rEn "$pattern" "$PLUGIN_DIR" --include="*.php" --include="*.js" 2>/dev/null \
		| grep -vE "$SKIP_DIRS" || true)

	if [[ -n "$findings" ]]; then
		while IFS= read -r line; do
			local loc=$(echo "$line" | cut -d: -f1-2)
			local rel=$(realpath --relative-to="$PLUGIN_DIR" "$(echo "$line" | cut -d: -f1)"):$(echo "$line" | cut -d: -f2)
			local snippet=$(echo "$line" | cut -d: -f3- | sed 's/^[[:space:]]*//' | cut -c1-80)
			if is_allowlisted "$label" "$rel"; then
				continue
			fi
			if [[ "$severity" == "ERROR" ]]; then
				log_error "[${label}] ${rel}: ${snippet}"
				ERRORS=$((ERRORS + 1))
			else
				log_warn "[${label}] ${rel}: ${snippet}"
				WARNINGS=$((WARNINGS + 1))
			fi
		done <<< "$findings"
	fi
}

log_info "Cleanup scan: ${SLUG}..."

# ERROR: debug output
scan_pattern ERROR '\bvar_dump\s*\(' 'var_dump('
scan_pattern ERROR '\bprint_r\s*\(' 'print_r('
scan_pattern ERROR 'console\.(log|debug|trace)\s*\(' 'console.log('
scan_pattern ERROR '\bdebugger\s*;' 'debugger;'

# ERROR: explicit dev/test markers
scan_pattern ERROR 'TODO:\s*REMOVE' 'TODO: REMOVE'
scan_pattern ERROR 'REMOVE BEFORE RELEASE' 'REMOVE BEFORE RELEASE'
scan_pattern ERROR 'DO NOT SHIP' 'DO NOT SHIP'
scan_pattern ERROR '@TODO\s+DEBUG' '@TODO DEBUG'
scan_pattern ERROR '@TEMP\b' '@TEMP'
scan_pattern ERROR '@HACK\b' '@HACK'

# ERROR: plugin should never define WP_DEBUG
scan_pattern ERROR "define\(\s*['\"]WP_DEBUG['\"]" 'define(WP_DEBUG)'

# ERROR: debug die/exit
scan_pattern ERROR "\b(die|exit)\(\s*['\"](here|test|debug|foo|bar)['\"]" 'die(debug)'

# ERROR: hardcoded dev URLs
scan_pattern ERROR '\blocalhost[:/]' 'localhost URL'
scan_pattern ERROR '\.test[/:"'\'']' '.test URL'
scan_pattern ERROR '\.local[/:"'\'']' '.local URL'
scan_pattern ERROR '\b192\.168\.[0-9]+\.[0-9]+' 'private IP'

# ERROR: empty catch blocks
scan_pattern ERROR 'catch\s*\([^)]+\)\s*\{\s*\}' 'empty catch'

# ERROR: debug files at plugin root (not in subdirs)
for f in debug.php test.php scratch.php scratchpad.php debug-*.php test-*.php scratch-*.php; do
	for match in "${PLUGIN_DIR}"/${f}; do
		[[ -e "$match" ]] || continue
		log_error "[debug file] $(realpath --relative-to="$PLUGIN_DIR" "$match")"
		ERRORS=$((ERRORS + 1))
	done
done

# WARNING: TODOs and FIXMEs (ok to ship but noted)
scan_pattern WARN '(TODO|FIXME):' 'TODO/FIXME'
scan_pattern WARN '\bsleep\s*\(\s*[0-9]+\s*\)' 'sleep()'
scan_pattern WARN '@since\s+(Unreleased|TBD)' '@since Unreleased'

echo
if (( ERRORS > 0 )); then
	log_error "Cleanup scan: ${ERRORS} error(s), ${WARNINGS} warning(s)"
	log_error "Fix the errors above, or add justified entries to ${SLUG}/.cleanup-allowlist"
	exit 1
elif (( WARNINGS > 0 )); then
	log_warn "Cleanup scan: clean (${WARNINGS} warning(s) — ok to ship)"
	exit 0
else
	log_ok "Cleanup scan: clean"
	exit 0
fi
