// engine/spec-versioning/migrate-format.ts — Detect + migrate spec format version (SPEC-717)
import { renderHistoryYaml } from './render-history.js';
// ---------------------------------------------------------------------------
// Detection
// ---------------------------------------------------------------------------
/**
 * Returns the spec_format_version detected from a frontmatter object.
 * Missing field => '0.x'. Anything else must match the SpecFormatVersion enum.
 *
 * @pure — no I/O.
 */
export function detectSpecFormatVersion(frontmatter) {
    const raw = frontmatter.spec_format_version;
    if (raw === undefined || raw === null) {
        return '0.x';
    }
    if (raw === '1.0') {
        return '1.0';
    }
    // Unknown value — treat as legacy
    return '0.x';
}
// ---------------------------------------------------------------------------
// Migration
// ---------------------------------------------------------------------------
/**
 * Pure function that, given raw spec.md content, returns either the original
 * content (if already at format 1.0 and idempotent) or the migrated content
 * with `spec_format_version`, `spec_version`, and an initial `history` entry.
 *
 * Running this function twice on the same input is guaranteed to return
 * `{ migrated: false }` on the second call.
 */
export function migrateFrontmatterToCurrentFormat(content, opts) {
    const fmRe = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
    const m = fmRe.exec(content);
    if (!m?.[1] || m[2] === undefined) {
        // No frontmatter — cannot migrate
        return { content, migrated: false };
    }
    const yamlBlock = m[1];
    const body = m[2];
    // Parse minimal KV for detection
    const fm = parseFrontmatterKV(yamlBlock);
    const formatVersion = detectSpecFormatVersion(fm);
    // Already migrated — idempotent
    if (formatVersion === '1.0') {
        return { content, migrated: false };
    }
    // Build migration history entry
    const entry = {
        at: new Date().toISOString(),
        kind: 'format-migrated',
        spec_version_from: null,
        spec_version_to: '1.0.0',
        by: opts.sessionId,
        reason: 'Auto-migrated to spec_format_version 1.0',
    };
    let yaml = yamlBlock;
    // Inject spec_format_version
    yaml = appendOrReplaceField(yaml, 'spec_format_version', '"1.0"');
    // Inject spec_version
    yaml = appendOrReplaceField(yaml, 'spec_version', '"1.0.0"');
    // Replace or append history block
    const historyYaml = renderHistoryYaml([entry]);
    const histBlockRe = /^history:.*?(?=^\w|$)/ms;
    if (histBlockRe.test(yaml)) {
        yaml = yaml.replace(histBlockRe, historyYaml + '\n');
    }
    else {
        yaml = `${yaml}\n${historyYaml}`;
    }
    const migrated = `---\n${yaml}\n---\n${body}`;
    return { content: migrated, migrated: true };
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function parseFrontmatterKV(yamlBlock) {
    const result = {};
    for (const line of yamlBlock.split('\n')) {
        const mx = /^(\w[\w_-]*):\s*(.+)$/.exec(line.trim());
        if (mx?.[1] && mx[2] !== undefined) {
            result[mx[1]] = mx[2].replace(/^["']|["']$/g, '');
        }
    }
    return result;
}
function appendOrReplaceField(yamlBlock, key, value) {
    const re = new RegExp(`^(${key}:\\s*).*$`, 'm');
    if (re.test(yamlBlock)) {
        return yamlBlock.replace(re, `${key}: ${value}`);
    }
    return `${yamlBlock}\n${key}: ${value}`;
}
//# sourceMappingURL=migrate-format.js.map