"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createFileEditInsertTool = void 0;
const ai_1 = require("ai");
const toolDefinitions_1 = require("../../utils/tools/toolDefinitions");
const fileCommon_1 = require("./fileCommon");
const tools_1 = require("../../types/tools");
const file_edit_operation_1 = require("./file_edit_operation");
const Runtime_1 = require("../../runtime/Runtime");
const fileExists_1 = require("../../utils/runtime/fileExists");
const helpers_1 = require("../../utils/runtime/helpers");
/**
 * File edit insert tool factory for AI assistant
 * Creates a tool that allows the AI to insert content at a specific line position
 * @param config Required configuration including working directory
 */
const createFileEditInsertTool = (config) => {
    return (0, ai_1.tool)({
        description: toolDefinitions_1.TOOL_DEFINITIONS.file_edit_insert.description,
        inputSchema: toolDefinitions_1.TOOL_DEFINITIONS.file_edit_insert.schema,
        execute: async ({ file_path, line_offset, content, create }, { abortSignal }) => {
            try {
                // Validate no redundant path prefix (must come first to catch absolute paths)
                const redundantPrefixValidation = (0, fileCommon_1.validateNoRedundantPrefix)(file_path, config.cwd, config.runtime);
                if (redundantPrefixValidation) {
                    return {
                        success: false,
                        error: redundantPrefixValidation.error,
                    };
                }
                const pathValidation = (0, fileCommon_1.validatePathInCwd)(file_path, config.cwd, config.runtime);
                if (pathValidation) {
                    return {
                        success: false,
                        error: pathValidation.error,
                    };
                }
                if (line_offset < 0) {
                    return {
                        success: false,
                        error: `line_offset must be non-negative (got ${line_offset})`,
                        note: `${tools_1.EDIT_FAILED_NOTE_PREFIX} The line_offset must be >= 0.`,
                    };
                }
                // Use runtime's normalizePath method to resolve paths correctly for both local and SSH runtimes
                const resolvedPath = config.runtime.normalizePath(file_path, config.cwd);
                // Check if file exists using runtime
                const exists = await (0, fileExists_1.fileExists)(config.runtime, resolvedPath, abortSignal);
                if (!exists) {
                    if (!create) {
                        return {
                            success: false,
                            error: `File not found: ${file_path}. To create it, set create: true`,
                            note: `${tools_1.EDIT_FAILED_NOTE_PREFIX} File does not exist. Set create: true to create it, or check the file path.`,
                        };
                    }
                    // Create empty file using runtime helper
                    try {
                        await (0, helpers_1.writeFileString)(config.runtime, resolvedPath, "", abortSignal);
                    }
                    catch (err) {
                        if (err instanceof Runtime_1.RuntimeError) {
                            return {
                                success: false,
                                error: err.message,
                            };
                        }
                        throw err;
                    }
                }
                return (0, file_edit_operation_1.executeFileEditOperation)({
                    config,
                    filePath: file_path,
                    abortSignal,
                    operation: (originalContent) => {
                        const lines = originalContent.split("\n");
                        if (line_offset > lines.length) {
                            return {
                                success: false,
                                error: `line_offset ${line_offset} is beyond file length (${lines.length} lines)`,
                                note: `${tools_1.EDIT_FAILED_NOTE_PREFIX} The file has ${lines.length} lines. ${tools_1.NOTE_READ_FILE_RETRY}`,
                            };
                        }
                        // Handle newline behavior:
                        // - If content ends with \n and we're not at EOF, strip it (join will add it back)
                        // - If content ends with \n and we're at EOF, keep it (join won't add trailing newline)
                        // - If content doesn't end with \n, keep as-is (join will add newlines between lines)
                        const contentEndsWithNewline = content.endsWith("\n");
                        const insertingAtEnd = line_offset === lines.length;
                        const shouldStripTrailingNewline = contentEndsWithNewline && !insertingAtEnd;
                        const normalizedContent = shouldStripTrailingNewline ? content.slice(0, -1) : content;
                        const newLines = [
                            ...lines.slice(0, line_offset),
                            normalizedContent,
                            ...lines.slice(line_offset),
                        ];
                        const newContent = newLines.join("\n");
                        return {
                            success: true,
                            newContent,
                            metadata: {},
                        };
                    },
                });
            }
            catch (error) {
                if (error && typeof error === "object" && "code" in error && error.code === "EACCES") {
                    return {
                        success: false,
                        error: `Permission denied: ${file_path}`,
                    };
                }
                const message = error instanceof Error ? error.message : String(error);
                return {
                    success: false,
                    error: `Failed to insert content: ${message}`,
                };
            }
        },
    });
};
exports.createFileEditInsertTool = createFileEditInsertTool;
//# sourceMappingURL=file_edit_insert.js.map