/**
 * Migrate BRAIN memory from JSONL files to brain.db SQLite tables.
 * Reads .cleo/memory/patterns.jsonl and .cleo/memory/learnings.jsonl
 * and inserts into brain_patterns and brain_learnings tables.
 *
 * Idempotent: checks for existing entries by ID to skip duplicates.
 *
 * @task T5129
 * @epic T5149
 */
import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import { getBrainAccessor } from '../store/brain-accessor.js';
/**
 * Read a JSONL file and parse each line as JSON.
 * Returns parsed objects and any parse error messages.
 */
function readJsonlFile(filePath) {
    if (!existsSync(filePath)) {
        return { entries: [], errors: [] };
    }
    const content = readFileSync(filePath, 'utf-8').trim();
    if (!content) {
        return { entries: [], errors: [] };
    }
    const entries = [];
    const errors = [];
    for (const line of content.split('\n')) {
        const trimmed = line.trim();
        if (!trimmed)
            continue;
        try {
            entries.push(JSON.parse(trimmed));
        }
        catch (_err) {
            errors.push(`Failed to parse line: ${trimmed.slice(0, 80)}...`);
        }
    }
    return { entries, errors };
}
/**
 * Migrate BRAIN memory data from JSONL files to brain.db.
 *
 * Reads:
 * - .cleo/memory/patterns.jsonl -> brain_patterns table
 * - .cleo/memory/learnings.jsonl -> brain_learnings table
 *
 * Skips entries where the ID already exists in the database (idempotent).
 *
 * @task T5129
 */
export async function migrateBrainData(projectRoot) {
    const accessor = await getBrainAccessor(projectRoot);
    const result = {
        patternsImported: 0,
        learningsImported: 0,
        duplicatesSkipped: 0,
        errors: [],
    };
    // Migrate patterns
    const patternsPath = join(projectRoot, '.cleo', 'memory', 'patterns.jsonl');
    const { entries: patterns, errors: patternErrors } = readJsonlFile(patternsPath);
    result.errors.push(...patternErrors);
    for (const p of patterns) {
        try {
            // Check if already exists
            const existing = await accessor.getPattern(p.id);
            if (existing) {
                result.duplicatesSkipped++;
                continue;
            }
            const row = {
                id: p.id,
                type: mapPatternType(p.type),
                pattern: p.pattern,
                context: p.context,
                frequency: p.frequency ?? 1,
                successRate: p.successRate ?? null,
                impact: mapImpact(p.impact),
                antiPattern: p.antiPattern ?? null,
                mitigation: p.mitigation ?? null,
                examplesJson: JSON.stringify(p.examples ?? []),
                extractedAt: p.extractedAt ?? new Date().toISOString().replace('T', ' ').slice(0, 19),
                updatedAt: p.updatedAt?.replace('T', ' ').slice(0, 19) ?? null,
            };
            await accessor.addPattern(row);
            result.patternsImported++;
        }
        catch (err) {
            result.errors.push(`Pattern ${p.id}: ${err instanceof Error ? err.message : String(err)}`);
        }
    }
    // Migrate learnings
    const learningsPath = join(projectRoot, '.cleo', 'memory', 'learnings.jsonl');
    const { entries: learnings, errors: learningErrors } = readJsonlFile(learningsPath);
    result.errors.push(...learningErrors);
    for (const l of learnings) {
        try {
            // Check if already exists
            const existing = await accessor.getLearning(l.id);
            if (existing) {
                result.duplicatesSkipped++;
                continue;
            }
            const row = {
                id: l.id,
                insight: l.insight,
                source: l.source,
                confidence: l.confidence,
                actionable: l.actionable ?? false,
                application: l.application ?? null,
                applicableTypesJson: JSON.stringify(l.applicableTypes ?? []),
                createdAt: l.createdAt ?? new Date().toISOString().replace('T', ' ').slice(0, 19),
                updatedAt: l.updatedAt?.replace('T', ' ').slice(0, 19) ?? null,
            };
            await accessor.addLearning(row);
            result.learningsImported++;
        }
        catch (err) {
            result.errors.push(`Learning ${l.id}: ${err instanceof Error ? err.message : String(err)}`);
        }
    }
    return result;
}
/**
 * Map JSONL pattern type to brain schema enum.
 * Falls back to 'workflow' for unrecognized types.
 */
function mapPatternType(type) {
    const valid = ['workflow', 'blocker', 'success', 'failure', 'optimization'];
    if (valid.includes(type)) {
        return type;
    }
    return 'workflow';
}
/**
 * Map JSONL impact level to brain schema enum.
 * Returns null for unrecognized values.
 */
function mapImpact(impact) {
    if (!impact)
        return null;
    const valid = ['low', 'medium', 'high'];
    if (valid.includes(impact)) {
        return impact;
    }
    return null;
}
//# sourceMappingURL=brain-migration.js.map