/**
 * NERF Directory Validation — Safeguards against running in dangerous directories.
 *
 * Prevents NERF from creating .nerf/ structures in system paths, home directories,
 * or other locations where writing project scaffolding would be harmful.
 */
import { realpathSync, readdirSync } from "node:fs";
import { homedir, platform, tmpdir } from "node:os";
import { resolve } from "node:path";
// ─── Blocked Paths ──────────────────────────────────────────────────────────────
/** Paths where NERF must never create .nerf/ — no override possible. */
const UNIX_BLOCKED_PATHS = new Set([
    "/",
    "/bin",
    "/sbin",
    "/usr",
    "/usr/bin",
    "/usr/sbin",
    "/usr/lib",
    "/usr/local",
    "/usr/local/bin",
    "/etc",
    "/var",
    "/var/tmp",
    "/dev",
    "/proc",
    "/sys",
    "/boot",
    "/lib",
    "/lib64",
    // macOS-specific
    "/System",
    "/Library",
    "/Applications",
    "/Volumes",
    "/private",
    "/private/var",
    "/private/etc",
    "/private/tmp",
]);
const WINDOWS_BLOCKED_PATHS = new Set([
    "C:\\",
    "C:\\Windows",
    "C:\\Windows\\System32",
    "C:\\Program Files",
    "C:\\Program Files (x86)",
]);
// ─── Core Validation ────────────────────────────────────────────────────────────
/**
 * Validate whether a directory is safe for NERF to operate in.
 *
 * Checks in order:
 * 1. Blocked system paths (hard stop)
 * 2. Home directory itself (hard stop)
 * 3. Temp directory root (hard stop)
 * 4. High entry count heuristic (warning)
 */
export function validateDirectory(dirPath) {
    // Resolve to absolute + follow symlinks so aliases can't bypass checks
    let resolved;
    try {
        resolved = realpathSync(resolve(dirPath));
    }
    catch {
        // If we can't resolve, use the raw resolved path
        resolved = resolve(dirPath);
    }
    // Normalize trailing slashes for consistent comparison.
    // Special cases: "/" → "/" (not ""), "C:\" → "C:\" (not "C:")
    let normalized = resolved.replace(/[/\\]+$/, "");
    if (normalized === "") {
        normalized = "/";
    }
    else if (/^[A-Za-z]:$/.test(normalized)) {
        normalized = normalized + "\\";
    }
    // ── Check 1: Blocked system paths ──────────────────────────────────────
    const blockedPaths = platform() === "win32" ? WINDOWS_BLOCKED_PATHS : UNIX_BLOCKED_PATHS;
    if (blockedPaths.has(normalized)) {
        return {
            safe: false,
            severity: "blocked",
            reason: `Refusing to run in system directory: ${normalized}. NERF must be run inside a project directory.`,
        };
    }
    // ── Check 2: Home directory itself (not subdirs) ───────────────────────
    let resolvedHome;
    try {
        resolvedHome = realpathSync(resolve(homedir())).replace(/[/\\]+$/, "");
    }
    catch {
        resolvedHome = resolve(homedir()).replace(/[/\\]+$/, "");
    }
    if (normalized === resolvedHome) {
        return {
            safe: false,
            severity: "blocked",
            reason: `Refusing to run in your home directory (${normalized}). NERF must be run inside a project directory, not $HOME.`,
        };
    }
    // ── Check 3: Temp directory root ───────────────────────────────────────
    let resolvedTmp;
    try {
        resolvedTmp = realpathSync(resolve(tmpdir())).replace(/[/\\]+$/, "");
    }
    catch {
        resolvedTmp = resolve(tmpdir()).replace(/[/\\]+$/, "");
    }
    if (normalized === resolvedTmp) {
        return {
            safe: false,
            severity: "blocked",
            reason: `Refusing to run in the system temp directory (${normalized}). Use a project subdirectory instead.`,
        };
    }
    // ── Check 4: Suspiciously large directory (heuristic warning) ──────────
    try {
        const entries = readdirSync(normalized);
        if (entries.length > 200) {
            return {
                safe: false,
                severity: "warning",
                reason: `This directory has ${entries.length} entries, which suggests it may not be a project directory. Are you sure you want to initialize NERF here?`,
            };
        }
    }
    catch {
        // Can't read directory — let downstream handle the error
    }
    return { safe: true, severity: "ok" };
}
/**
 * Assert that a directory is safe for NERF operations.
 * Throws with a descriptive message if the directory is blocked.
 * Returns the validation result for warnings (caller decides how to handle).
 */
export function assertSafeDirectory(dirPath) {
    const result = validateDirectory(dirPath);
    if (result.severity === "blocked") {
        throw new Error(result.reason);
    }
    return result;
}
