import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { isProcessAlive, removeDaemonLock, scanAllLockfiles, } from '../daemon/lock.js';
const STALE_DAEMON_AGE_MS = 60 * 60 * 1000;
function sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}
function readInstalledVersion() {
    try {
        const packageJsonPath = fileURLToPath(new URL('../../package.json', import.meta.url));
        const parsed = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
        return parsed.version ?? null;
    }
    catch {
        return process.env.npm_package_version ?? null;
    }
}
export async function runPostinstallCleanup(options = {}) {
    const now = options.now ?? Date.now();
    const currentVersion = options.currentVersion ?? readInstalledVersion();
    const dryRun = options.dryRun ?? false;
    const isAlive = options.isProcessAliveFn ?? isProcessAlive;
    const killProcess = options.killProcessFn ?? ((pid, signal) => process.kill(pid, signal));
    const sleepFn = options.sleepFn ?? sleep;
    const summary = {
        scanned: 0,
        staleLockfilesRemoved: 0,
        staleDaemonsKilled: 0,
    };
    for (const entry of scanAllLockfiles(options.stateRoot)) {
        summary.scanned += 1;
        const { lockPath, lock } = entry;
        const alive = isAlive(lock.pid);
        if (!alive) {
            if (!dryRun) {
                try {
                    removeDaemonLock(lockPath, { pid: lock.pid });
                }
                catch {
                    // Best effort cleanup — keep going.
                }
            }
            summary.staleLockfilesRemoved += 1;
            continue;
        }
        const ageMs = Math.max(0, now - lock.startedAt);
        if (ageMs < STALE_DAEMON_AGE_MS) {
            continue;
        }
        if (!dryRun) {
            try {
                killProcess(lock.pid, 'SIGTERM');
            }
            catch {
                // Best effort cleanup — keep going.
            }
            await sleepFn(2_000);
            if (isAlive(lock.pid)) {
                try {
                    killProcess(lock.pid, 'SIGKILL');
                }
                catch {
                    // Best effort cleanup — keep going.
                }
            }
            try {
                removeDaemonLock(lockPath, { pid: lock.pid });
            }
            catch {
                // Best effort cleanup — keep going.
            }
        }
        summary.staleDaemonsKilled += 1;
        summary.staleLockfilesRemoved += 1;
    }
    if (!options.silent) {
        process.stderr.write(`[nexus-prime] cleaned up ${summary.staleLockfilesRemoved} stale lockfiles, killed ${summary.staleDaemonsKilled} stale daemons`
            + (currentVersion ? ` (version ${currentVersion})` : '')
            + '\n');
    }
    return summary;
}
if (process.env.npm_lifecycle_event === 'postinstall') {
    void runPostinstallCleanup().catch(() => { });
}
