/**
 * Brain Maintenance Runner
 *
 * Combines temporal decay, memory consolidation, and embedding backfill
 * into a single idempotent maintenance pass. Designed to be run on a
 * schedule or on-demand via `cleo brain maintenance`.
 *
 * Steps run in order:
 *   1. Temporal decay   — reduce confidence of stale learnings
 *   2. Consolidation    — merge duplicate/similar old observations
 *   3. Embedding backfill — populate vectors for observations without them
 *
 * Each step is individually opt-outable via skip flags, making the
 * operation safe to re-run at any frequency.
 *
 * @task T143
 * @epic T134
 * @why Enable scheduled brain optimization via single command
 * @what Combined maintenance runner with CLI command and progress reporting
 */
import { reconcileOrphanedRefs } from '../store/cross-db-cleanup.js';
import { applyTemporalDecay, consolidateMemories } from './brain-lifecycle.js';
import { populateEmbeddings } from './brain-retrieval.js';
// ============================================================================
// Runner
// ============================================================================
/**
 * Run a combined brain maintenance pass: decay, consolidation, and embeddings.
 *
 * The three steps always run in the same order:
 *   1. `applyTemporalDecay` — decay stale learning confidence values
 *   2. `consolidateMemories` — merge clustered old observations
 *   3. `populateEmbeddings` — backfill missing vectors
 *
 * Each step is optional via the `skip*` flags. The function is idempotent:
 * re-running it when there is nothing to process returns zero counts.
 *
 * @param projectRoot - Absolute path to the project root (used to locate brain.db)
 * @param options - Optional skip flags and progress callback
 * @returns Aggregated counts from each step plus total wall-clock duration
 *
 * @example
 * ```ts
 * const result = await runBrainMaintenance('/my/project', {
 *   onProgress: (step, current, total) => {
 *     console.log(`[${step}] ${current}/${total}`);
 *   },
 * });
 * console.log(`Done in ${result.duration}ms`);
 * ```
 *
 * @task T143
 * @epic T134
 */
export async function runBrainMaintenance(projectRoot, options) {
    const { skipDecay = false, skipConsolidation = false, skipReconciliation = false, skipEmbeddings = false, onProgress, } = options ?? {};
    const startTime = Date.now();
    // Default zero values for each step (used when step is skipped).
    const decayResult = { affected: 0 };
    const consolidationResult = { merged: 0, removed: 0 };
    const reconciliationResult = {
        decisionsFixed: 0,
        observationsFixed: 0,
        linksRemoved: 0,
    };
    const embeddingsResult = {
        processed: 0,
        skipped: 0,
        errors: 0,
    };
    // Step 1: Temporal decay
    if (!skipDecay) {
        onProgress?.('decay', 0, 1);
        const raw = await applyTemporalDecay(projectRoot);
        decayResult.affected = raw.updated;
        onProgress?.('decay', 1, 1);
    }
    // Step 2: Memory consolidation
    if (!skipConsolidation) {
        onProgress?.('consolidation', 0, 1);
        const raw = await consolidateMemories(projectRoot);
        consolidationResult.merged = raw.merged;
        consolidationResult.removed = raw.archived;
        onProgress?.('consolidation', 1, 1);
    }
    // Step 3: Cross-DB orphaned reference reconciliation
    if (!skipReconciliation) {
        onProgress?.('reconciliation', 0, 1);
        const raw = await reconcileOrphanedRefs(projectRoot);
        reconciliationResult.decisionsFixed = raw.decisionsFixed;
        reconciliationResult.observationsFixed = raw.observationsFixed;
        reconciliationResult.linksRemoved = raw.linksRemoved;
        onProgress?.('reconciliation', 1, 1);
    }
    // Step 4: Embedding backfill (with per-item progress relay)
    if (!skipEmbeddings) {
        const raw = await populateEmbeddings(projectRoot, {
            onProgress: (current, total) => {
                onProgress?.('embeddings', current, total);
            },
        });
        embeddingsResult.processed = raw.processed;
        embeddingsResult.skipped = raw.skipped;
        embeddingsResult.errors = raw.errors;
    }
    return {
        decay: decayResult,
        consolidation: consolidationResult,
        reconciliation: reconciliationResult,
        embeddings: embeddingsResult,
        duration: Date.now() - startTime,
    };
}
//# sourceMappingURL=brain-maintenance.js.map