/**
 * Update check orchestrator
 *
 * Main entry point for the auto-update check. Coordinates
 * version checking, prompt display, and update execution.
 */
import { execFileSync } from "child_process";
import * as fs from "fs/promises";
import * as path from "path";
import { log, note } from "@clack/prompts";
import { readInstallState } from "../../cli/installTracking.js";
import { getAvailableUpdate, refreshVersionCache, } from "../../cli/updates/npmRegistryCheck.js";
import { dismissVersion } from "../../cli/updates/versionCache.js";
import { getUpdateCommand, showUpdatePrompt } from "./updatePrompt.js";
/**
 * Try to read the autoupdate setting from the nearest .nori-config.json
 *
 * @returns The autoupdate setting, or null if not found
 */
const loadAutoupdateSetting = async () => {
    const candidates = [path.join(process.cwd(), ".nori-config.json")];
    for (const configPath of candidates) {
        try {
            const content = await fs.readFile(configPath, "utf-8");
            const config = JSON.parse(content);
            if (config.autoupdate === "enabled" || config.autoupdate === "disabled") {
                return config.autoupdate;
            }
        }
        catch {
            continue;
        }
    }
    return null;
};
/**
 * Detect the package manager used to install nori-skillsets.
 * Reads the persisted install state first (available even outside npm scripts),
 * falls back to npm_config_user_agent env var, defaults to npm.
 *
 * @returns The detected package manager name
 */
const detectInstallSource = async () => {
    // Read persisted install state (written during npm install)
    const state = await readInstallState();
    if (state?.install_source != null && state.install_source !== "") {
        return state.install_source;
    }
    // Fallback: env var is available when running via npm scripts
    const userAgent = process.env.npm_config_user_agent ?? "";
    if (userAgent.includes("bun"))
        return "bun";
    if (userAgent.includes("pnpm"))
        return "pnpm";
    if (userAgent.includes("yarn"))
        return "yarn";
    if (userAgent.includes("npm"))
        return "npm";
    // Default to npm rather than "unknown" - it's the most common case
    return "npm";
};
/**
 * Check for available updates and prompt the user if one exists.
 * This is the main entry point called from the CLI startup.
 *
 * @param args - Arguments
 * @param args.currentVersion - The currently running version
 * @param args.isInteractive - Whether we're in interactive mode
 * @param args.isSilent - Whether silent mode is on
 * @param args.autoupdate - The autoupdate config setting
 */
export const checkForUpdateAndPrompt = async (args) => {
    const { currentVersion, isInteractive, isSilent } = args;
    try {
        // Load autoupdate setting from config if not provided
        const autoupdate = args.autoupdate ?? (await loadAutoupdateSetting());
        // Early exits
        if (autoupdate === "disabled")
            return;
        if (isSilent)
            return;
        // Fire-and-forget background refresh
        void refreshVersionCache();
        // Check for available update using cached data
        const update = await getAvailableUpdate({ currentVersion });
        if (update == null)
            return;
        const choice = await showUpdatePrompt({
            currentVersion,
            latestVersion: update.latestVersion,
            isInteractive,
        });
        if (choice === "update") {
            const installSource = await detectInstallSource();
            const updateCommand = getUpdateCommand({ installSource });
            if (updateCommand == null) {
                log.warn("Could not detect package manager. Please update manually:");
                note("npm install -g nori-skillsets@latest", "Update Manually");
                return;
            }
            log.info(`Updating nori-skillsets...`);
            try {
                execFileSync(updateCommand.command, updateCommand.args, {
                    stdio: "inherit",
                });
                log.success(`Update complete! Please re-run your command.`);
                process.exit(0);
            }
            catch {
                log.error(`Update failed. Try manually: ${updateCommand.displayCommand}`);
            }
        }
        else if (choice === "dismiss") {
            await dismissVersion({ version: update.latestVersion });
        }
    }
    catch (err) {
        if (isInteractive) {
            log.error(`Update check failed (non-fatal): ${err}`);
        }
    }
};
//# sourceMappingURL=checkForUpdate.js.map