import { countPlannedOperations } from './sync.utils.js';
function summarize(scopePlans) {
    return {
        plannedOperations: countPlannedOperations(scopePlans),
        applied: 0,
        failed: 0,
        skipped: scopePlans.reduce((total, scopePlan) => {
            const extensionSkipped = scopePlan.materializationExtensions.reduce((count, extension) => count +
                extension.operations.filter((operation) => operation.action === 'skip').length, 0);
            return (total +
                scopePlan.plan.entries.filter((entry) => entry.operation === 'skip')
                    .length +
                extensionSkipped);
        }, 0),
    };
}
function formatMaterializationExtensions(scopePlan) {
    return scopePlan.materializationExtensions
        .map((extension) => {
        const lines = extension.operations.map((operation) => {
            const entry = operation.entryName ? ` (${operation.entryName})` : '';
            return `- ${operation.provider}:${operation.target}:${operation.action} ${operation.path}${entry} (${operation.reason})`;
        });
        return `${extension.provider} extension (dry-run)\n${lines.join('\n')}`;
    })
        .join('\n\n');
}
function formatDryRunOutput(scopePlans, dependencies) {
    if (scopePlans.length === 0) {
        return dependencies.formatSyncPlan({
            scope: 'project',
            entries: [],
            removals: [],
        }, false);
    }
    return scopePlans
        .map((scopePlan) => {
        const syncOutput = dependencies.formatSyncPlan(scopePlan.plan, false);
        const extensionOutput = formatMaterializationExtensions(scopePlan);
        return extensionOutput
            ? `Scope: ${scopePlan.scope}\n${syncOutput}\n\n${extensionOutput}`
            : `Scope: ${scopePlan.scope}\n${syncOutput}`;
    })
        .join('\n\n');
}
export function runSyncDryRun(context, scopePlans, dependencies) {
    const summary = summarize(scopePlans);
    const providerMismatches = scopePlans
        .map((scopePlan) => scopePlan.providerMismatches)
        .filter((mismatch) => mismatch !== undefined);
    const materializationExtensions = scopePlans.flatMap((scopePlan) => scopePlan.materializationExtensions);
    const codexExtensions = materializationExtensions
        .filter((extension) => extension.provider === 'codex')
        .map((extension) => ({
        operations: extension.operations.map((operation) => ({
            action: operation.action,
            target: operation.target,
            path: operation.path,
            reason: operation.reason,
            roleName: operation.entryName,
        })),
        managedRoles: extension.managedEntries,
        aggregateConfigHash: extension.aggregateHash,
    }));
    if (context.json) {
        context.logger.json({
            scope: context.scope,
            dryRun: true,
            plans: scopePlans.map((scopePlan) => scopePlan.plan),
            summary,
            providerMismatches,
            materializationExtensions,
            codexExtensions,
        });
    }
    else {
        context.logger.info(formatDryRunOutput(scopePlans, dependencies));
        context.logger.warn('\nDry-run only: no filesystem changes were made.');
        if (summary.plannedOperations > 0) {
            context.logger.info('Run without --dry-run to apply changes.');
        }
        else {
            context.logger.info('No changes to apply.');
        }
    }
    process.exitCode = 0;
}
