/**
 * doc-insert handler — PR-5a-1
 *
 * Markdown section upsert into a target file (e.g. CLAUDE.md).
 *
 * Semantics:
 *   - If the target file does not exist, it is created with the section.
 *   - If the section header already exists (## <header>), the section body
 *     is replaced in-place (idempotent replace).
 *   - If the section header is absent, the header + body is appended at the
 *     end of the file.
 *
 * Idempotency: applying the same doc-insert twice produces the same file.
 *
 * @connexum/ai-governance PR-5a-1
 */
import * as fs from 'fs';
import * as path from 'path';
import { computeUnifiedDiff } from '../diff-utils.js';
/**
 * Compute the updated file content for a doc-insert.
 * Returns before + after strings; caller decides whether to write.
 */
export function applyDocInsert(agentDir, payload) {
    const filePath = path.resolve(agentDir, payload.targetFile);
    const before = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : '';
    const header = `## ${payload.sectionHeader}`;
    const body = payload.sectionContent;
    const after = upsertSection(before, header, body);
    const alreadyApplied = after === before;
    const relPath = path.relative(agentDir, filePath);
    const diff = {
        filePath: relPath,
        before,
        after,
        unifiedDiff: computeUnifiedDiff(before, after, relPath),
    };
    return { filePath, before, after, diff, alreadyApplied };
}
/**
 * Write the updated file to disk.
 */
export function writeDocInsert(agentDir, payload) {
    const result = applyDocInsert(agentDir, payload);
    if (!result.alreadyApplied) {
        fs.mkdirSync(path.dirname(result.filePath), { recursive: true });
        fs.writeFileSync(result.filePath, result.after, 'utf-8');
    }
    return result;
}
// ---------------------------------------------------------------------------
// Section upsert logic
// ---------------------------------------------------------------------------
/**
 * Insert or replace an H2 section in a markdown document.
 *
 * The section runs from the header line up to (but not including) the next
 * H2 header (## ...) or end-of-file. The body replaces the entire section
 * content (the text between this header and the next).
 */
function upsertSection(content, header, body) {
    const lines = content.split('\n');
    const headerIdx = lines.findIndex((l) => l.trimEnd() === header);
    // Normalise body: ensure it ends with a newline but doesn't have trailing blank lines
    const normBody = body.endsWith('\n') ? body : body + '\n';
    if (headerIdx === -1) {
        // Append: add a blank separator if file has content
        const separator = content.trim() ? '\n' : '';
        return content + separator + header + '\n' + normBody;
    }
    // Replace: find where this section ends (next H2 or EOF)
    let endIdx = lines.length;
    for (let i = headerIdx + 1; i < lines.length; i++) {
        if (lines[i].startsWith('## ')) {
            endIdx = i;
            break;
        }
    }
    // Build replacement
    const before = lines.slice(0, headerIdx);
    const after = lines.slice(endIdx);
    const newSection = [header, ...normBody.split('\n')];
    // Remove the trailing empty string from the split if normBody ends with \n
    if (newSection[newSection.length - 1] === '') {
        newSection.pop();
    }
    const merged = [...before, ...newSection, '', ...after];
    // Collapse multiple trailing blank lines
    let result = merged.join('\n');
    // Ensure single trailing newline
    result = result.replace(/\n+$/, '') + '\n';
    return result;
}
//# sourceMappingURL=doc-insert.js.map