/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { updateAllUpdatableExtensions, checkForAllExtensionUpdates, updateExtension, } from '../../config/extensions/update.js';
import { checkForExtensionUpdate } from '../../config/extensions/github.js';
import { getErrorMessage } from '../../utils/errors.js';
import { ExtensionUpdateState } from '../../ui/state/extensions.js';
import { coreEvents, debugLogger } from '@google/gemini-cli-core';
import { ExtensionManager } from '../../config/extension-manager.js';
import { requestConsentNonInteractive } from '../../config/extensions/consent.js';
import { loadSettings } from '../../config/settings.js';
import { promptForSetting } from '../../config/extensions/extensionSettings.js';
import { exitCli } from '../utils.js';
const updateOutput = (info) => `Extension "${info.name}" successfully updated: ${info.originalVersion} → ${info.updatedVersion}.`;
export async function handleUpdate(args) {
    const workspaceDir = process.cwd();
    const settings = loadSettings(workspaceDir).merged;
    const extensionManager = new ExtensionManager({
        workspaceDir,
        requestConsent: requestConsentNonInteractive,
        requestSetting: promptForSetting,
        settings,
    });
    const extensions = await extensionManager.loadExtensions();
    if (args.name) {
        try {
            const extension = extensions.find((extension) => extension.name === args.name);
            if (!extension) {
                if (extensions.length === 0) {
                    coreEvents.emitFeedback('error', `Extension "${args.name}" not found.\n\nNo extensions installed.`);
                    return;
                }
                const installedExtensions = extensions
                    .map((extension) => `${extension.name} (${extension.version})`)
                    .join('\n');
                coreEvents.emitFeedback('error', `Extension "${args.name}" not found.\n\nInstalled extensions:\n${installedExtensions}\n\nRun "gemini extensions list" for details.`);
                return;
            }
            if (!extension.installMetadata) {
                debugLogger.log(`Unable to install extension "${args.name}" due to missing install metadata`);
                return;
            }
            const updateState = await checkForExtensionUpdate(extension, extensionManager);
            if (updateState !== ExtensionUpdateState.UPDATE_AVAILABLE) {
                debugLogger.log(`Extension "${args.name}" is already up to date.`);
                return;
            }
            const updatedExtensionInfo = (await updateExtension(extension, extensionManager, updateState, () => { }, settings.experimental?.extensionReloading));
            if (updatedExtensionInfo.originalVersion !==
                updatedExtensionInfo.updatedVersion) {
                debugLogger.log(`Extension "${args.name}" successfully updated: ${updatedExtensionInfo.originalVersion} → ${updatedExtensionInfo.updatedVersion}.`);
            }
            else {
                debugLogger.log(`Extension "${args.name}" is already up to date.`);
            }
        }
        catch (error) {
            debugLogger.error(getErrorMessage(error));
        }
    }
    if (args.all) {
        try {
            const extensionState = new Map();
            await checkForAllExtensionUpdates(extensions, extensionManager, (action) => {
                if (action.type === 'SET_STATE') {
                    extensionState.set(action.payload.name, {
                        status: action.payload.state,
                    });
                }
            });
            let updateInfos = await updateAllUpdatableExtensions(extensions, extensionState, extensionManager, () => { });
            updateInfos = updateInfos.filter((info) => info.originalVersion !== info.updatedVersion);
            if (updateInfos.length === 0) {
                debugLogger.log('No extensions to update.');
                return;
            }
            debugLogger.log(updateInfos.map((info) => updateOutput(info)).join('\n'));
        }
        catch (error) {
            debugLogger.error(getErrorMessage(error));
        }
    }
}
export const updateCommand = {
    command: 'update [<name>] [--all]',
    describe: 'Updates all extensions or a named extension to the latest version.',
    builder: (yargs) => yargs
        .positional('name', {
        describe: 'The name of the extension to update.',
        type: 'string',
    })
        .option('all', {
        describe: 'Update all extensions.',
        type: 'boolean',
    })
        .conflicts('name', 'all')
        .check((argv) => {
        if (!argv.all && !argv.name) {
            throw new Error('Either an extension name or --all must be provided');
        }
        return true;
    }),
    handler: async (argv) => {
        await handleUpdate({
            // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
            name: argv['name'],
            // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
            all: argv['all'],
        });
        await exitCli();
    },
};
//# sourceMappingURL=update.js.map