// Création d'un nouveau projet : un dossier `<root>/<name>` créé sous une racine existante, dans
// lequel on lance ensuite une session. Couche PURE (testable sans fs) : la création réelle du
// dossier, le `git init` et le spawn vivent dans `routes/projects.ts`.
import { join } from 'node:path';
import { isSafeAbsolutePath } from './git.js';

/**
 * Valide un nom de projet : UN SEUL segment de dossier. Anti-traversal de base : refuse les noms
 * vides, trop longs, `.`/`..`, et tout caractère de séparation (`/`, `\`) ou NUL. La résolution du
 * chemin complet (et sa re-validation) est faite par {@link resolveProjectDir}.
 */
export function isSafeProjectName(name: string): boolean {
  const n = name.trim();
  if (n.length === 0 || n.length > 255) return false;
  if (n === '.' || n === '..') return false;
  return !/[/\\\0]/.test(n);
}

/**
 * Résout le dossier de projet `<root>/<name>`. Suppose `root` déjà validé absolu et existant par
 * l'appelant ; re-valide le chemin final via {@link isSafeAbsolutePath} (défense en profondeur).
 * Lève si `name` est invalide ou si le chemin résultant échappe l'arborescence.
 */
export function resolveProjectDir(root: string, name: string): string {
  if (!isSafeProjectName(name)) {
    throw Object.assign(new Error(`Invalid project name: ${name}`), { statusCode: 400 });
  }
  const dir = join(root, name.trim());
  if (!isSafeAbsolutePath(dir)) {
    throw Object.assign(new Error(`Unsafe project path: ${dir}`), { statusCode: 400 });
  }
  return dir;
}
