#!/usr/bin/env bash
# survey.sh — детерминированная разведка раздутости проекта (0 токенов на то, что стабильно).
# Собирает: git-чистоту, размер по языкам, топ самых длинных файлов, кандидатов в мёртвые зависимости.
# Ничего не меняет. Usage: survey.sh [PROJECT_DIR]   (по умолчанию — текущая папка)
set -euo pipefail

DIR="${1:-$PWD}"
cd "$DIR"

EXCLUDE_PATHS=( -not -path '*/.git/*' -not -path '*/node_modules/*' -not -path '*/.venv/*'
  -not -path '*/venv/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/.next/*'
  -not -path '*/__pycache__/*' -not -path '*/migrations/*' -not -path '*/alembic/versions/*' )

echo "=== PROJECT: $DIR ==="

# --- git baseline (для гарантии отката) ---
if git rev-parse --git-dir >/dev/null 2>&1; then
  echo "=== GIT ==="
  echo "branch: $(git rev-parse --abbrev-ref HEAD)  HEAD: $(git rev-parse --short HEAD)"
  if git diff --quiet && git diff --cached --quiet; then echo "state: CLEAN (откат безопасен)"
  else echo "state: DIRTY (⚠ есть незакоммиченные правки — зафиксируй перед аудитом с правками)"; fi
else
  echo "=== GIT ==="; echo "state: NOT A REPO (⚠ правки применять НЕЛЬЗЯ — только read-only аудит)"
fi

# --- размер по языкам ---
echo "=== SIZE BY LANG ==="
for ext in py js ts tsx jsx go rs java kt swift rb php; do
  files=$(find . -name "*.$ext" "${EXCLUDE_PATHS[@]}" 2>/dev/null)
  [ -z "$files" ] && continue
  loc=$(echo "$files" | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}')
  n=$(echo "$files" | grep -c .)
  printf "  %-5s %5s files  %8s loc\n" ".$ext" "$n" "$loc"
done

# --- топ длинных файлов (кандидаты в раздутость) ---
echo "=== TOP 15 LONGEST FILES ==="
find . \( -name '*.py' -o -name '*.js' -o -name '*.ts' -o -name '*.tsx' -o -name '*.jsx' \
  -o -name '*.go' -o -name '*.rs' -o -name '*.swift' \) "${EXCLUDE_PATHS[@]}" 2>/dev/null \
  | xargs wc -l 2>/dev/null | sort -rn | grep -v ' total$' | head -15

# --- кандидаты в мёртвые зависимости (Python) ---
if [ -f pyproject.toml ]; then
  echo "=== PY DEP CANDIDATES (объявлены в [project].dependencies, но не грепаются — ПЕРЕПРОВЕРЬ) ==="
  # только runtime-зависимости из [project].dependencies (НЕ dev-tools, НЕ [tool.*])
  deps=$(python3 - <<'PYEOF' 2>/dev/null
import re, sys
try:
    import tomllib
    with open("pyproject.toml","rb") as f: d=tomllib.load(f)
    for spec in d.get("project",{}).get("dependencies",[]):
        name=re.split(r"[<>=!~;\[\s]", spec.strip())[0]
        if name and name.lower()!="python": print(name)
except Exception:
    pass
PYEOF
)
  [ -z "$deps" ] && echo "  (нет [project].dependencies или Python<3.11 без tomllib — пропущено)"
  for d in $deps; do
    # нормализуем имя пакета в вероятный import (- → _)
    mod=$(echo "$d" | tr '-' '_')
    if ! grep -rqiE "(import|from)\s+($d|$mod)\b" --include='*.py' . 2>/dev/null; then
      echo "  ? $d  (import '$mod' не найден — м.б. динамический/транзитивный, проверь)"
    fi
  done
fi

# --- кандидаты в мёртвые зависимости (Node) ---
if [ -f package.json ] && command -v node >/dev/null 2>&1; then
  echo "=== NODE DEP CANDIDATES (объявлены, но не импортируются — ПЕРЕПРОВЕРЬ) ==="
  node -e '
    const p=require("./package.json"); const cp=require("child_process");
    const deps=Object.keys(p.dependencies||{});
    for(const d of deps){
      try{cp.execSync(`grep -rqE "(from|require\\(|import)[^\\n]*['"'"'\"]${d.replace(/[.*+?^${}()|[\]\\]/g,"\\\\$&")}" --include=*.{js,ts,jsx,tsx,mjs,cjs} . 2>/dev/null`);}
      catch(e){console.log(`  ? ${d}  (не импортируется явно — проверь)`);}
    }' 2>/dev/null || echo "  (node-проверка пропущена)"
fi

echo "=== DONE ==="
