import { randomUUID } from "node:crypto";
import { copyFileSync, existsSync, mkdirSync, renameSync, rmSync } from "node:fs";
import { basename, dirname, join, relative, resolve, toNamespacedPath } from "node:path";
import { APP_NAME } from "../config.js";
import { getCwdRelativePath } from "./paths.js";
const QUARANTINE_DIR_NAME = `.${APP_NAME}-native-quarantine`;
function normalizePath(path) {
    return toNamespacedPath(resolve(path));
}
function getQuarantineRoot(packageDir) {
    let current = resolve(packageDir);
    while (true) {
        if (basename(current).toLowerCase() === "node_modules") {
            return join(current, QUARANTINE_DIR_NAME);
        }
        const parent = dirname(current);
        if (parent === current) {
            return undefined;
        }
        current = parent;
    }
}
function getLoadedSharedObjectsInPackageDir(packageDir) {
    const sharedObjects = process.report.getReport().sharedObjects;
    if (!Array.isArray(sharedObjects)) {
        return [];
    }
    const root = normalizePath(packageDir).toLowerCase();
    const seen = new Set();
    const loadedFiles = [];
    for (const value of sharedObjects) {
        if (typeof value !== "string") {
            continue;
        }
        const filePath = normalizePath(value);
        const comparisonPath = filePath.toLowerCase();
        if (getCwdRelativePath(comparisonPath, root) === undefined || seen.has(comparisonPath)) {
            continue;
        }
        seen.add(comparisonPath);
        loadedFiles.push(filePath);
    }
    return loadedFiles;
}
export function cleanupWindowsSelfUpdateQuarantine(packageDir) {
    const quarantineRoot = getQuarantineRoot(packageDir);
    if (!quarantineRoot) {
        return;
    }
    try {
        rmSync(quarantineRoot, { recursive: true, force: true });
    }
    catch {
        // A previous Atomic process may still be exiting and holding a native addon.
    }
}
export function quarantineWindowsNativeDependencies(packageDir) {
    const resolvedPackageDir = normalizePath(packageDir);
    const quarantineRoot = getQuarantineRoot(resolvedPackageDir);
    if (!quarantineRoot) {
        return;
    }
    const loadedFiles = getLoadedSharedObjectsInPackageDir(resolvedPackageDir);
    if (loadedFiles.length === 0) {
        return;
    }
    const quarantineRunDir = join(quarantineRoot, `${Date.now()}-${process.pid}-${randomUUID()}`);
    for (const loadedFile of loadedFiles) {
        if (!existsSync(loadedFile)) {
            continue;
        }
        const quarantinePath = join(quarantineRunDir, relative(resolvedPackageDir, loadedFile));
        mkdirSync(dirname(quarantinePath), { recursive: true });
        renameSync(loadedFile, quarantinePath);
        copyFileSync(quarantinePath, loadedFile);
    }
}
//# sourceMappingURL=windows-self-update.js.map