/**
 * @license
 * Copyright 2025 HopCode Team
 * SPDX-License-Identifier: Apache-2.0
 */
import { getInstallationInfo } from './installationInfo.js';
import { updateEventEmitter } from './updateEventEmitter.js';
import { MessageType } from '../ui/types.js';
import { spawnWrapper } from './spawnWrapper.js';
import os from 'node:os';
export function handleAutoUpdate(info, settings, projectRoot, spawnFn = spawnWrapper) {
    if (!info) {
        return;
    }
    // enableAutoUpdate is checked in interactive.tsx before calling this function,
    // so if we get here, auto-update is enabled (or undefined, which defaults to enabled).
    const isAutoUpdateEnabled = settings.merged.general?.enableAutoUpdate !== false;
    const installationInfo = getInstallationInfo(projectRoot, isAutoUpdateEnabled);
    let combinedMessage = info.message;
    if (installationInfo.updateMessage) {
        combinedMessage += `\n${installationInfo.updateMessage}`;
    }
    updateEventEmitter.emit('update-received', {
        message: combinedMessage,
    });
    // Don't automatically run the update if auto-update is disabled or no update command
    if (!installationInfo.updateCommand || !isAutoUpdateEnabled) {
        return;
    }
    const isNightly = info.update.latest.includes('nightly');
    const updateCommand = installationInfo.updateCommand.replace('@latest', isNightly ? '@nightly' : `@${info.update.latest}`);
    const isWindows = os.platform() === 'win32';
    const shell = isWindows ? 'cmd.exe' : 'bash';
    const shellArgs = isWindows ? ['/c', updateCommand] : ['-c', updateCommand];
    const updateProcess = spawnFn(shell, shellArgs, { stdio: 'pipe' });
    let errorOutput = '';
    updateProcess.stderr.on('data', (data) => {
        errorOutput += data.toString();
    });
    updateProcess.on('close', (code) => {
        if (code === 0) {
            updateEventEmitter.emit('update-success', {
                message: 'Update successful! The new version will be used on your next run.',
            });
        }
        else {
            updateEventEmitter.emit('update-failed', {
                message: `Automatic update failed. Please try updating manually. (command: ${updateCommand}, stderr: ${errorOutput.trim()})`,
            });
        }
    });
    updateProcess.on('error', (err) => {
        updateEventEmitter.emit('update-failed', {
            message: `Automatic update failed. Please try updating manually. (error: ${err.message})`,
        });
    });
    return updateProcess;
}
export function setUpdateHandler(addItem, setUpdateInfo, isIdleRef = { current: true }) {
    let successfullyInstalled = false;
    const pendingNotifications = [];
    const addItemOrDefer = (item) => {
        if (isIdleRef.current) {
            addItem(item, Date.now());
        }
        else {
            pendingNotifications.push(item);
        }
    };
    const handleUpdateRecieved = (info) => {
        setUpdateInfo(info);
        const savedMessage = info.message;
        setTimeout(() => {
            if (!successfullyInstalled) {
                addItemOrDefer({
                    type: MessageType.INFO,
                    text: savedMessage,
                });
            }
            setUpdateInfo(null);
        }, 60000);
    };
    const handleUpdateFailed = () => {
        setUpdateInfo(null);
        addItemOrDefer({
            type: MessageType.ERROR,
            text: `Automatic update failed. Please try updating manually`,
        });
    };
    const handleUpdateSuccess = () => {
        successfullyInstalled = true;
        setUpdateInfo(null);
        addItemOrDefer({
            type: MessageType.INFO,
            text: `Update successful! The new version will be used on your next run.`,
        });
    };
    const handleUpdateInfo = (data) => {
        addItemOrDefer({
            type: MessageType.INFO,
            text: data.message,
        });
    };
    updateEventEmitter.on('update-received', handleUpdateRecieved);
    updateEventEmitter.on('update-failed', handleUpdateFailed);
    updateEventEmitter.on('update-success', handleUpdateSuccess);
    updateEventEmitter.on('update-info', handleUpdateInfo);
    const cleanup = () => {
        updateEventEmitter.off('update-received', handleUpdateRecieved);
        updateEventEmitter.off('update-failed', handleUpdateFailed);
        updateEventEmitter.off('update-success', handleUpdateSuccess);
        updateEventEmitter.off('update-info', handleUpdateInfo);
        pendingNotifications.length = 0;
    };
    const flush = () => {
        while (pendingNotifications.length > 0) {
            const item = pendingNotifications.shift();
            addItem(item, Date.now());
        }
    };
    return { cleanup, flush };
}
//# sourceMappingURL=handleAutoUpdate.js.map