import { readFile, writeFile } from 'node:fs/promises';
// Fix P1: JSON.parse(raw) as Type → JSON.parse(raw) as Partial<Type>
const JSON_PARSE_FIX = /(JSON\.parse\([^)]+\)\s+as\s+)(?!Partial<)([A-Z]\w*)/g;
// Fix P2: x?.field.method() → x?.field?.method()
// Match: ?.word.word( — replace middle . with ?.
const OPTIONAL_CHAIN_FIX = /(\?\.[a-zA-Z_]+)\.([a-zA-Z_]+\()/g;
/**
 * Produces a simple unified-diff-style string comparing old and new lines.
 */
function buildDiff(filePath, oldLines, newLines) {
    const parts = [`--- ${filePath}`, `+++ ${filePath} (fixed)`];
    const maxLen = Math.max(oldLines.length, newLines.length);
    for (let i = 0; i < maxLen; i++) {
        const oldLine = oldLines[i];
        const newLine = newLines[i];
        if (oldLine !== newLine) {
            if (oldLine !== undefined) {
                parts.push(`-${oldLine}`);
            }
            if (newLine !== undefined) {
                parts.push(`+${newLine}`);
            }
        }
    }
    return parts.join('\n');
}
/**
 * Applies deterministic fixes to TypeScript/JavaScript content.
 * Returns the fixed content and a diff string.
 */
function applyFixes(content) {
    let fixed = content;
    // Fix P1: JSON.parse without Partial
    fixed = fixed.replace(JSON_PARSE_FIX, '$1Partial<$2>');
    // Fix P2: incomplete optional chaining
    // Apply multiple passes to handle chained cases like ?.a.b.c(
    let prev = '';
    while (prev !== fixed) {
        prev = fixed;
        fixed = fixed.replace(OPTIONAL_CHAIN_FIX, '$1?.$2');
    }
    return { fixed, changed: fixed !== content };
}
/**
 * Fixes crash risks in a TypeScript/JavaScript file.
 * If dryRun=true, calculates and returns the diff without writing.
 */
export async function fixTypeScriptFile(filePath, dryRun) {
    let content;
    try {
        content = await readFile(filePath, 'utf-8');
    }
    catch {
        return null;
    }
    const { fixed, changed } = applyFixes(content);
    if (!changed) {
        return null;
    }
    const oldLines = content.split('\n');
    const newLines = fixed.split('\n');
    const diff = buildDiff(filePath, oldLines, newLines);
    const applied = countChangedLines(oldLines, newLines);
    if (!dryRun) {
        await writeFile(filePath, fixed, 'utf-8');
    }
    return { file: filePath, applied, diff };
}
function countChangedLines(oldLines, newLines) {
    const maxLen = Math.max(oldLines.length, newLines.length);
    let count = 0;
    for (let i = 0; i < maxLen; i++) {
        if (oldLines[i] !== newLines[i]) {
            count++;
        }
    }
    return count;
}
//# sourceMappingURL=typescript-fixer.js.map