import { execFile } from 'node:child_process';
import { spawn } from 'node:child_process';
import { promisify } from 'node:util';
import { readPidFile, removePidFile } from '../../../../shared/services/pidFileManager.js';
import { PID_FILE_PATH } from '../../../../shared/services/daemonPaths.js';
const defaultExecFileAsync = promisify(execFile);
const RESTART_DELAY_SECONDS = 2;
function defaultSpawnDaemonDelayed(port, delaySec) {
    const args = ['start', '--skip-dependency-check'];
    if (port !== undefined) {
        args.push('--port', String(port));
    }
    const command = `sleep ${delaySec} && ${process.execPath} ${process.argv[1]} ${args.join(' ')}`;
    const child = spawn('sh', ['-c', command], {
        detached: true,
        stdio: 'ignore',
        env: { ...process.env, REVIEWFLOW_DAEMON: '1' },
    });
    child.unref();
}
function createDefaultDependencies() {
    return {
        execFileAsync: defaultExecFileAsync,
        killProcess: (pid, signal) => process.kill(pid, signal),
        spawnDaemonDelayed: defaultSpawnDaemonDelayed,
    };
}
export class SelfUpdateCliGateway {
    dependencies;
    constructor(dependencies) {
        this.dependencies = dependencies ?? createDefaultDependencies();
    }
    async runGlobalUpdate() {
        try {
            await this.dependencies.execFileAsync('npm', ['update', '-g', 'reviewflow']);
            return { success: true, error: null, permissionDenied: false };
        }
        catch (error) {
            const message = error instanceof Error ? error.message : 'Unknown error';
            const permissionDenied = error instanceof Error && error.message.includes('EACCES');
            return { success: false, error: message, permissionDenied };
        }
    }
    async restartDaemon(serverPort) {
        const pidFileContent = readPidFile(PID_FILE_PATH);
        const port = pidFileContent?.port ?? serverPort;
        const targetPid = pidFileContent?.pid ?? process.pid;
        removePidFile(PID_FILE_PATH);
        this.dependencies.spawnDaemonDelayed(port, RESTART_DELAY_SECONDS);
        try {
            this.dependencies.killProcess(targetPid, 'SIGTERM');
        }
        catch {
            // Process may already be dead
        }
    }
}
//# sourceMappingURL=selfUpdate.cli.gateway.js.map