import { DryRunRecorder, createDryRunFileSystem, formatDryRunOperations } from "../utils/dry-run.js";
import { FEEDBACK_URL } from "./constants.js";
export function createCommandContextFactory(init) {
    const { fs } = init;
    const create = (options) => {
        if (!options.dryRun) {
            return {
                fs,
                runCommand: options.runner,
                runCommandWithEnv(command, args, runOptions) {
                    return options.runner(command, args, {
                        cwd: runOptions?.cwd,
                        env: runOptions?.env
                    });
                },
                flushDryRun() { },
                complete(messages) {
                    options.logger.success(messages.success);
                },
                finalize() {
                    options.logger.feedback("Problems?", FEEDBACK_URL);
                }
            };
        }
        const recorder = new DryRunRecorder();
        const proxyFs = createDryRunFileSystem(fs, recorder);
        const recordedCommands = new Set();
        let hasEmittedOperations = false;
        const flush = (emitIfEmpty = false) => {
            const operations = recorder.drain();
            if (operations.length === 0) {
                if (emitIfEmpty && !hasEmittedOperations) {
                    const lines = formatDryRunOperations(operations);
                    for (const line of lines) {
                        options.logger.info(line);
                    }
                }
                return;
            }
            hasEmittedOperations = true;
            for (const line of formatDryRunOperations(operations)) {
                const base = extractBaseCommand(line);
                if (!recordedCommands.has(base)) {
                    options.logger.info(line);
                    recordedCommands.add(base);
                }
            }
        };
        return {
            fs: proxyFs,
            runCommand: options.runner,
            runCommandWithEnv(command, args, runOptions) {
                return options.runner(command, args, {
                    cwd: runOptions?.cwd,
                    env: runOptions?.env
                });
            },
            flushDryRun({ emitIfEmpty } = {}) {
                flush(Boolean(emitIfEmpty));
            },
            complete(messages) {
                options.logger.dryRun(messages.dry);
                flush(true);
            },
            finalize() {
                options.logger.feedback("Problems?", FEEDBACK_URL);
            }
        };
    };
    return { create };
}
export function createLoggingCommandRunner(runner, logger) {
    return async (command, args, options) => {
        const rendered = [command, ...args].join(" ").trim();
        const suffix = options?.cwd ? ` (cwd: ${options.cwd})` : "";
        logger.verbose(`> ${rendered}${suffix}`);
        if (options) {
            return runner(command, args, options);
        }
        return runner(command, args);
    };
}
function extractBaseCommand(message) {
    const raw = stripAnsi(message);
    const detailIndex = raw.indexOf(" #");
    return detailIndex >= 0 ? raw.slice(0, detailIndex).trim() : raw.trim();
}
function stripAnsi(value) {
    return value.replace(/\u001B\[[0-9;]*m/g, "");
}
//# sourceMappingURL=context.js.map