#!/usr/bin/env bash
# Read-only naming audit and rename-plan generator for apps/<app-name>.
# Usage: audit.naming.sh APP_NAME [--details] [--summary] [--backup] [--fix]
set -euo pipefail
APPS_ROOT="${APPS_ROOT:-/home/intel145/websites/apps}"
APP="${1:-}"; shift || true
DETAILS=0; SUMMARY=0; BACKUP=0; FIX=0
usage(){ cat <<'EOF'
Usage: audit.naming.sh APP_NAME [options]

Options:
  --details   Print every naming violation with its suggested target.
  --summary   Print category totals only after the report.
  --backup    Include backup/editor residue findings in the report.
  --fix       Generate a review-only rename.APP_NAME.sh plan; it does not rename files.
  -h,--help   Show help.

Naming policy:
  Files:       lowercase letters and digits in base name only; no '-' or '_'.
  Directories: lowercase letters, digits, and '_' only; no '-' or '.'.
  Extensions:  final '.' before the extension is allowed.
EOF
}
[[ -n "$APP" && "$APP" != '-h' && "$APP" != '--help' ]] || { usage; exit 2; }
[[ "$APP" =~ ^[A-Za-z0-9][A-Za-z0-9_-]*$ ]] || { echo 'ERROR: invalid app name.' >&2; exit 2; }
while (($#)); do case "$1" in --details) DETAILS=1;; --summary) SUMMARY=1;; --backup) BACKUP=1;; --fix) FIX=1;; -h|--help) usage; exit 0;; *) echo "ERROR: unknown option: $1" >&2; exit 2;; esac; shift; done
root_real="$(cd "$APPS_ROOT" && pwd -P)"; app_dir="$APPS_ROOT/$APP"; [[ -d "$app_dir" ]] || { echo "ERROR: app not found: $app_dir" >&2; exit 2; }; app_real="$(cd "$app_dir" && pwd -P)"
case "$app_real/" in "$root_real/"*) ;; *) echo 'ERROR: resolved app path escapes APPS_ROOT.' >&2; exit 2;; esac
files=0; dirs=0; backups=0; collisions=0; declare -a details plan
suggest_file(){ local p="$1" n b e target; n="${p##*/}"; b="$n"; e=""; [[ "$n" == *.* ]] && { b="${n%.*}"; e=".${n##*.}"; }; target="$(printf '%s' "$b" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9')$e"; printf '%s' "${p%/*}/$target"; }
suggest_dir(){ local p="$1" n target; n="${p##*/}"; target="$(printf '%s' "$n" | tr '[:upper:]' '[:lower:]' | tr '-' '_' | tr -cd 'a-z0-9_')"; printf '%s' "${p%/*}/$target"; }
add(){ local kind="$1" src="$2" dst="$3"; details+=("$kind|$src|$dst"); }
while IFS= read -r -d '' p; do rel="${p#$app_real/}"; n="${p##*/}"; b="${n%.*}"; [[ "$n" == *.* ]] || b="$n"; if [[ ! "$b" =~ ^[a-z0-9]+$ ]]; then ((files+=1)) || true; add FILE "$rel" "${p#$app_real/}"; details[-1]="FILE|$rel|${p#$app_real/}/$(suggest_file "$p" | sed "s#^$app_real/##")"; fi; done < <(find "$app_real" -type f -print0)
while IFS= read -r -d '' p; do [[ "$p" == "$app_real" ]] && continue; rel="${p#$app_real/}"; n="${p##*/}"; if [[ ! "$n" =~ ^[a-z0-9_]+$ ]]; then ((dirs+=1)) || true; add DIR "$rel" "${p#$app_real/}/$(suggest_dir "$p" | sed "s#^$app_real/##")"; fi; done < <(find "$app_real" -type d -print0)
if ((BACKUP)); then while IFS= read -r -d '' p; do ((backups+=1)) || true; details+=("BACKUP|${p#$app_real/}|move outside served app root or delete after review"); done < <(find "$app_real" -type f \( -iname '*.bak' -o -iname '*.backup' -o -iname '*~' -o -iname '*.swp' \) -print0); fi
printf 'Naming audit\nApp: %s\nRoot: %s\n\n' "$APP" "$app_real"
printf '%-8s %s\n' STATUS MESSAGE
if ((files==0)); then printf '%-8s %s\n' PASS 'NAME-FILE: file base names comply.'; else printf '%-8s %s\n' WARN "NAME-FILE: $files file names violate lowercase/no-hyphen/no-underscore policy."; fi
if ((dirs==0)); then printf '%-8s %s\n' PASS 'NAME-DIR: directory names comply.'; else printf '%-8s %s\n' WARN "NAME-DIR: $dirs directory names violate lowercase/underscore-only policy."; fi
if ((BACKUP)); then printf '%-8s %s\n' INFO "BACKUP: $backups backup/editor residue files found."; fi
if ((DETAILS)); then printf '\nDetails\n-------\n'; for x in "${details[@]}"; do IFS='|' read -r kind src dst <<< "$x"; case "$kind" in FILE) printf '[NAME-FILE] %s -> %s\n' "$src" "$dst";; DIR) printf '[NAME-DIR]  %s -> %s\n' "$src" "$dst";; BACKUP) printf '[BACKUP]    %s -> %s\n' "$src" "$dst";; esac; done; fi
if ((FIX)); then planfile="$(pwd)/rename.${APP}.sh"; { echo '#!/usr/bin/env bash'; echo '# REVIEW THIS FILE BEFORE RUNNING. Generated rename plan; no automatic reference updates.'; echo 'set -euo pipefail'; printf 'cd %q\n' "$app_real"; echo '# Rename deepest paths first. Update PHP includes, require calls, URLs, imports, and links before executing.'; for x in "${details[@]}"; do IFS='|' read -r kind src dst <<< "$x"; [[ "$kind" == FILE || "$kind" == DIR ]] || continue; printf '# REVIEW: mv -- %q %q\n' "$src" "$dst"; done; } > "$planfile"; chmod 0700 "$planfile"; printf '\nPlan written for review: %s\n' "$planfile"; fi
if ((SUMMARY)); then printf '\nSummary: file_violations=%d directory_violations=%d backup_findings=%d\n' "$files" "$dirs" "$backups"; fi
[[ "$files" -eq 0 && "$dirs" -eq 0 ]] || exit 1
