"use strict";
/**
 * Minimal unified-diff generator (no external deps).
 *
 * Used by remediation handlers to produce human-readable diffs for the
 * mandatory dry-run display. Intentionally simple: line-level Myers diff
 * with +3 lines of context. Good enough for code file display.
 *
 * @connexum/ai-governance PR-5a
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeUnifiedDiff = computeUnifiedDiff;
function computeUnifiedDiff(before, after, filePath) {
    if (before === after)
        return '';
    const beforeLines = before.split('\n');
    const afterLines = after.split('\n');
    const hunks = myersDiff(beforeLines, afterLines);
    if (hunks.length === 0)
        return '';
    const header = `--- a/${filePath}\n+++ b/${filePath}\n`;
    return header + hunks.join('\n');
}
function myersDiff(a, b) {
    // Build edit script via simple LCS table
    const m = a.length;
    const n = b.length;
    const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
    for (let i = m - 1; i >= 0; i--) {
        for (let j = n - 1; j >= 0; j--) {
            if (a[i] === b[j]) {
                dp[i][j] = dp[i + 1][j + 1] + 1;
            }
            else {
                dp[i][j] = Math.max(dp[i + 1][j], dp[i][j + 1]);
            }
        }
    }
    // Trace edits
    const edits = [];
    let i = 0;
    let j = 0;
    while (i < m && j < n) {
        if (a[i] === b[j]) {
            edits.push({ type: 'equal', value: a[i] });
            i++;
            j++;
        }
        else if (dp[i + 1][j] >= dp[i][j + 1]) {
            edits.push({ type: 'delete', value: a[i] });
            i++;
        }
        else {
            edits.push({ type: 'insert', value: b[j] });
            j++;
        }
    }
    while (i < m) {
        edits.push({ type: 'delete', value: a[i++] });
    }
    while (j < n) {
        edits.push({ type: 'insert', value: b[j++] });
    }
    // Render hunks with context=3
    const CONTEXT = 3;
    const hunks = [];
    const changed = [];
    for (let idx = 0; idx < edits.length; idx++) {
        if (edits[idx].type !== 'equal')
            changed.push(idx);
    }
    if (changed.length === 0)
        return [];
    let idx = 0;
    let aLine = 1;
    let bLine = 1;
    while (idx < edits.length) {
        // Find next change
        const nextChange = changed.find((c) => c >= idx);
        if (nextChange === undefined)
            break;
        const hunkStart = Math.max(0, nextChange - CONTEXT);
        // skip equal lines before hunk start
        while (idx < hunkStart) {
            const e = edits[idx];
            if (e.type === 'equal') {
                aLine++;
                bLine++;
            }
            else if (e.type === 'delete')
                aLine++;
            else
                bLine++;
            idx++;
        }
        // Find hunk end
        let hunkEnd = nextChange + CONTEXT;
        for (const c of changed) {
            if (c > nextChange && c <= hunkEnd) {
                hunkEnd = c + CONTEXT;
            }
        }
        hunkEnd = Math.min(edits.length - 1, hunkEnd);
        // Collect hunk lines
        const hunkLines = [];
        const aHunkStart = aLine;
        const bHunkStart = bLine;
        let aCount = 0;
        let bCount = 0;
        for (let k = idx; k <= hunkEnd; k++) {
            const e = edits[k];
            if (e.type === 'equal') {
                hunkLines.push(` ${e.value}`);
                aCount++;
                bCount++;
            }
            else if (e.type === 'delete') {
                hunkLines.push(`-${e.value}`);
                aCount++;
            }
            else {
                hunkLines.push(`+${e.value}`);
                bCount++;
            }
        }
        hunks.push(`@@ -${aHunkStart},${aCount} +${bHunkStart},${bCount} @@`);
        hunks.push(...hunkLines);
        // Advance counters
        for (let k = idx; k <= hunkEnd; k++) {
            const e = edits[k];
            if (e.type === 'equal') {
                aLine++;
                bLine++;
            }
            else if (e.type === 'delete')
                aLine++;
            else
                bLine++;
        }
        idx = hunkEnd + 1;
    }
    return hunks;
}
//# sourceMappingURL=diff-utils.js.map