/**
 * Closure Hook Dispatcher
 *
 * Dispatches increment closure to external tool providers (GitHub, JIRA, ADO)
 * using the function-map pattern per ADR-0240.
 *
 * Design:
 * - Each provider is a function, not an adapter class
 * - Partial failures are isolated — one provider crashing doesn't block others
 * - incrementClosed is always true (closure is a local SpecWeave operation;
 *   external sync failures are non-blocking)
 * - Provider functions are injected for testability; production wiring
 *   lazy-imports plugin modules
 *
 * @module core/closure-dispatcher
 */
const PROVIDERS = ['github', 'jira', 'ado'];
/**
 * Dispatch closure to all enabled providers.
 *
 * Each provider runs independently — failures are captured, not propagated.
 * The function-map pattern (ADR-0240) keeps this flat and simple:
 * no adapter interfaces, no orchestrator classes.
 *
 * @param context - Project root and increment ID
 * @param config - Per-provider enable/disable flags
 * @param closeFns - Map of provider name → close function (injected for testing)
 */
export async function dispatchClosure(context, config, closeFns) {
    const successes = [];
    const failures = [];
    const tasks = PROVIDERS
        .filter((p) => config[p])
        .filter((p) => closeFns[p] != null)
        .map(async (provider) => {
        try {
            const result = await closeFns[provider](context);
            successes.push(result);
        }
        catch (error) {
            const msg = error instanceof Error ? error.message : String(error);
            failures.push({ provider, error: msg });
        }
    });
    await Promise.all(tasks);
    return {
        incrementClosed: true,
        successes,
        failures,
    };
}
/**
 * Build production close functions that lazy-import plugin modules.
 *
 * Called by SyncCoordinator to get the real provider functions.
 * Each function lazy-imports its plugin to avoid loading unused providers.
 */
export function buildProductionCloseFns() {
    return {
        github: async (ctx) => {
            const { SyncCoordinator } = await import('../sync/sync-coordinator.js');
            const coordinator = new SyncCoordinator({
                projectRoot: ctx.projectRoot,
                incrementId: ctx.incrementId,
            });
            const result = await coordinator.syncIncrementClosure();
            return {
                closed: (result?.closedIssues ?? []).map(String),
                provider: 'github',
            };
        },
        jira: async (ctx) => {
            const { SyncCoordinator } = await import('../sync/sync-coordinator.js');
            const coordinator = new SyncCoordinator({
                projectRoot: ctx.projectRoot,
                incrementId: ctx.incrementId,
            });
            const result = await coordinator.syncIncrementClosure();
            return {
                closed: (result?.closedIssues ?? []).map(String),
                provider: 'jira',
            };
        },
        ado: async (ctx) => {
            const { SyncCoordinator } = await import('../sync/sync-coordinator.js');
            const coordinator = new SyncCoordinator({
                projectRoot: ctx.projectRoot,
                incrementId: ctx.incrementId,
            });
            const result = await coordinator.syncIncrementClosure();
            return {
                closed: (result?.closedIssues ?? []).map(String),
                provider: 'ado',
            };
        },
    };
}
/**
 * Build closure config from SpecWeave hooks configuration.
 *
 * Reads the post_increment_done section and maps legacy flag names
 * to per-provider booleans. All default to true when not specified.
 */
export function buildClosureConfigFromHooks(hooks, syncSettings) {
    const canUpdate = syncSettings?.canUpdateExternalItems ?? true;
    const done = hooks?.post_increment_done;
    if (!canUpdate || !done) {
        return { github: false, jira: false, ado: false };
    }
    return {
        github: done.close_github_issue ?? done.close_external_issue ?? true,
        jira: done.close_jira_issue ?? done.close_external_issue ?? true,
        ado: done.close_ado_work_item ?? done.close_external_issue ?? true,
    };
}
//# sourceMappingURL=closure-dispatcher.js.map