#!/bin/zsh
set -euo pipefail

# По умолчанию считаем, что папки `common/` и `apps/` лежат рядом со скриптом.
# Если нужно — можно переопределить PROJECT_ROOT/OUTPUT_FILE через переменные окружения.
SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)"
PROJECT_ROOT="${PROJECT_ROOT:-$SCRIPT_DIR}"
OUTPUT_FILE="${OUTPUT_FILE:-$PROJECT_ROOT/code_dump.txt}"

# Нужно собрать ВСЕ PHP-файлы рекурсивно из двух корневых папок.
INCLUDE_DIRS=(
  "common"
  "apps"
)

INCLUDE_EXTENSIONS=(
  "php"
)

EXCLUDE_DIRS=(
  "runtime"
  "assets"
  "uploads"
  "upload"
  "vendor"
  "node_modules"
  ".git"
)

echo "📦 Dumping project code..."
echo "Project root: $PROJECT_ROOT"
echo "Output file:  $OUTPUT_FILE"

python3 - <<'PY' \
  "$PROJECT_ROOT" "$OUTPUT_FILE" \
  "$(printf "%s\n" "${INCLUDE_DIRS[@]}")" \
  "$(printf "%s\n" "${INCLUDE_EXTENSIONS[@]}")" \
  "$(printf "%s\n" "${EXCLUDE_DIRS[@]}")"
import os, sys
from pathlib import Path

project_root = Path(sys.argv[1]).resolve()
output_file  = Path(sys.argv[2]).resolve()

def parse_block(arg: str):
    # аргументы приходят блоками с \n
    return [x.strip() for x in arg.splitlines() if x.strip()]

include_dirs = parse_block(sys.argv[3])
extensions   = set(parse_block(sys.argv[4]))
exclude_dirs = set(parse_block(sys.argv[5]))

count = 0

def is_excluded(path: Path) -> bool:
    # исключаем если в пути встречается папка из exclude_dirs
    parts = set(path.parts)
    return any(ex in parts for ex in exclude_dirs)

output_file.parent.mkdir(parents=True, exist_ok=True)

with output_file.open("w", encoding="utf-8", errors="replace") as out:
    for rel_dir in include_dirs:
        root = (project_root / rel_dir)
        if not root.exists():
            print(f"⚠️  Skip missing dir: {rel_dir}")
            continue

        print(f"📁 Processing {rel_dir}")

        for dirpath, dirnames, filenames in os.walk(root):
            dp = Path(dirpath)

            # prune excluded dirs (важно: модифицируем dirnames inplace)
            dirnames[:] = [d for d in dirnames if d not in exclude_dirs]

            if is_excluded(dp):
                continue

            for fn in filenames:
                p = dp / fn
                if is_excluded(p):
                    continue
                ext = p.suffix.lower().lstrip(".")
                if ext not in extensions:
                    continue

                rel = p.relative_to(project_root)

                out.write("\n\n")
                out.write(f"===== FILE: {rel} =====\n")
                out.write("```\n")
                try:
                    out.write(p.read_text(encoding="utf-8", errors="replace"))
                except Exception as e:
                    out.write(f"\n[READ_ERROR] {e}\n")
                out.write("\n```\n")

                count += 1
                if count % 50 == 0:
                    print(f"… dumped {count} files")

print(f"✅ Done. Dumped {count} files into: {output_file}")
try:
    size = output_file.stat().st_size
    print(f"📏 Output size: {size/1024/1024:.2f} MB")
except Exception:
    pass
PY

ls -lh "$OUTPUT_FILE"