"use strict";
/**
 * Shared implementation for file edit replace tools
 *
 * These helpers are used by both string-based and line-based replace tools,
 * providing the core logic while keeping the tool definitions simple for AI providers.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleStringReplace = handleStringReplace;
exports.handleLineReplace = handleLineReplace;
const tools_1 = require("../../types/tools");
/**
 * Handle string-based replacement
 */
function handleStringReplace(args, originalContent) {
    const replaceCount = args.replace_count ?? 1;
    if (!originalContent.includes(args.old_string)) {
        return {
            success: false,
            error: "old_string not found in file. The text to replace must exist exactly as written in the file.",
            note: `${tools_1.EDIT_FAILED_NOTE_PREFIX} The old_string does not exist in the file. ${tools_1.NOTE_READ_FILE_FIRST_RETRY}`,
        };
    }
    const parts = originalContent.split(args.old_string);
    const occurrences = parts.length - 1;
    if (replaceCount === 1 && occurrences > 1) {
        return {
            success: false,
            error: `old_string appears ${occurrences} times in the file. Either expand the context to make it unique or set replace_count to ${occurrences} or -1.`,
            note: `${tools_1.EDIT_FAILED_NOTE_PREFIX} The old_string matched ${occurrences} locations. Add more surrounding context to make it unique, or set replace_count=${occurrences} to replace all occurrences.`,
        };
    }
    if (replaceCount > occurrences && replaceCount !== -1) {
        return {
            success: false,
            error: `replace_count is ${replaceCount} but old_string only appears ${occurrences} time(s) in the file.`,
            note: `${tools_1.EDIT_FAILED_NOTE_PREFIX} The replace_count=${replaceCount} is too high. Retry with replace_count=${occurrences} or -1.`,
        };
    }
    let newContent;
    let editsApplied;
    if (replaceCount === -1) {
        newContent = parts.join(args.new_string);
        editsApplied = occurrences;
    }
    else {
        let replacedCount = 0;
        let currentContent = originalContent;
        for (let i = 0; i < replaceCount; i++) {
            const index = currentContent.indexOf(args.old_string);
            if (index === -1) {
                break;
            }
            currentContent =
                currentContent.substring(0, index) +
                    args.new_string +
                    currentContent.substring(index + args.old_string.length);
            replacedCount++;
        }
        newContent = currentContent;
        editsApplied = replacedCount;
    }
    return {
        success: true,
        newContent,
        metadata: {
            edits_applied: editsApplied,
        },
    };
}
/**
 * Handle line-range replacement
 */
function handleLineReplace(args, originalContent) {
    const startIndex = args.start_line - 1;
    const endIndex = args.end_line - 1;
    if (args.start_line <= 0) {
        return {
            success: false,
            error: `start_line must be >= 1 (received ${args.start_line}).`,
            note: `${tools_1.EDIT_FAILED_NOTE_PREFIX} Line numbers must be >= 1.`,
        };
    }
    if (args.end_line < args.start_line) {
        return {
            success: false,
            error: `end_line must be >= start_line (received start ${args.start_line}, end ${args.end_line}).`,
            note: `${tools_1.EDIT_FAILED_NOTE_PREFIX} The end_line must be >= start_line.`,
        };
    }
    const lines = originalContent.split("\n");
    if (startIndex >= lines.length) {
        return {
            success: false,
            error: `start_line ${args.start_line} exceeds current file length (${lines.length}).`,
            note: `${tools_1.EDIT_FAILED_NOTE_PREFIX} The file has ${lines.length} lines. ${tools_1.NOTE_READ_FILE_RETRY}`,
        };
    }
    const clampedEndIndex = Math.min(endIndex, lines.length - 1);
    const currentRange = lines.slice(startIndex, clampedEndIndex + 1);
    if (args.expected_lines && !arraysEqual(currentRange, args.expected_lines)) {
        return {
            success: false,
            error: `expected_lines validation failed. Current lines [${currentRange.join("\n")}] differ from expected [${args.expected_lines.join("\n")}].`,
            note: `${tools_1.EDIT_FAILED_NOTE_PREFIX} The file content changed since you last read it. ${tools_1.NOTE_READ_FILE_AGAIN_RETRY}`,
        };
    }
    const before = lines.slice(0, startIndex);
    const after = lines.slice(clampedEndIndex + 1);
    const updatedLines = [...before, ...args.new_lines, ...after];
    const linesReplaced = currentRange.length;
    const totalDelta = args.new_lines.length - currentRange.length;
    return {
        success: true,
        newContent: updatedLines.join("\n"),
        metadata: {
            edits_applied: 1,
            lines_replaced: linesReplaced,
            line_delta: totalDelta,
        },
    };
}
function arraysEqual(a, b) {
    if (a.length !== b.length)
        return false;
    return a.every((value, index) => value === b[index]);
}
//# sourceMappingURL=file_edit_replace_shared.js.map