// engine/spec-migrator/unified-migration.ts — Merge technical.md into spec.md (SPEC-630)
import { readFile } from 'node:fs/promises';
import { atomicWriteFile } from '../safety/atomic-write-file.js';
/** Write a verified backup of a file before overwriting. Returns backup path. Throws on failure. */
async function writeVerifiedBackup(filePath) {
    const content = await readFile(filePath, 'utf-8');
    const bkPath = `${filePath}.bak.${Date.now()}`;
    await atomicWriteFile(bkPath, content);
    const verify = await readFile(bkPath, 'utf-8');
    if (verify !== content) {
        throw new Error(`backup verify failed for ${filePath}: content mismatch`);
    }
    return bkPath;
}
import { join } from 'node:path';
import { safeUnlink } from './git-aware-fs.js';
/**
 * Merge technical.md into spec.md under a `## Technical` section, then delete technical.md.
 * Idempotent: skips if spec.md already contains `## Technical`.
 *
 * @param specDir   Absolute path to the spec directory.
 * @param projectPath  Project root used for `safeUnlink` (git-aware deletion). Optional:
 *                     when omitted, falls back to plain unlink.
 */
export async function migrateToUnified(specDir, projectPath) {
    const specPath = join(specDir, 'spec.md');
    const techPath = join(specDir, 'technical.md');
    try {
        const specContent = await readFile(specPath, 'utf-8');
        if (/\n## Technical(\n|$)/.test(specContent)) {
            try {
                await readFile(techPath, 'utf-8');
                if (projectPath) {
                    await safeUnlink(projectPath, techPath);
                }
                else {
                    const { unlink } = await import('node:fs/promises');
                    await unlink(techPath);
                }
                return { specDir, merged: true, reason: 'already-unified' };
            }
            catch {
                /* no residual technical.md */
            }
            return { specDir, merged: false, reason: 'already-unified' };
        }
        let techContent;
        try {
            techContent = await readFile(techPath, 'utf-8');
        }
        catch {
            return { specDir, merged: false, reason: 'no-technical-md' };
        }
        // Strip YAML frontmatter block from technical.md before appending
        const techBody = techContent.replace(/^---\n[\s\S]*?\n---\n/, '').trim();
        const unified = `${specContent.trimEnd()}\n\n## Technical\n\n${techBody}\n`;
        // SPEC-771: backup spec.md before overwriting (verified write-back)
        try {
            await writeVerifiedBackup(specPath);
        }
        catch (backupErr) {
            return {
                specDir,
                merged: false,
                reason: 'error',
                error: `backup failed: ${String(backupErr)}`,
            };
        }
        // Write spec.md first, delete technical.md second — never leave both inconsistent
        await atomicWriteFile(specPath, unified);
        if (projectPath) {
            await safeUnlink(projectPath, techPath);
        }
        else {
            const { unlink } = await import('node:fs/promises');
            await unlink(techPath);
        }
        return { specDir, merged: true, reason: 'ok' };
    }
    catch (err) {
        return { specDir, merged: false, reason: 'error', error: String(err) };
    }
}
/** Migrate all SPEC-* dirs under projectPath to unified format. Best-effort: never throws. */
export async function migrateAllSpecsToUnified(projectPath) {
    const { glob } = await import('glob');
    const dirs = await glob(join(projectPath, 'planu/specs/SPEC-*'));
    let mergedCount = 0;
    let skippedCount = 0;
    const errors = [];
    for (const dir of dirs) {
        const r = await migrateToUnified(dir, projectPath);
        if (r.merged) {
            mergedCount++;
        }
        else if (!r.error) {
            skippedCount++;
        }
        if (r.error) {
            errors.push(`${dir}: ${r.error}`);
        }
    }
    return { mergedCount, skippedCount, errors };
}
//# sourceMappingURL=unified-migration.js.map