"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileSystemTool = void 0;
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
const inquirer_1 = __importDefault(require("inquirer"));
const chalk_1 = __importDefault(require("chalk"));
class FileSystemTool {
    name = 'filesystem';
    requireConfirmation;
    constructor(requireConfirmation = true) {
        this.requireConfirmation = requireConfirmation;
    }
    definition = {
        type: 'function',
        function: {
            name: 'filesystem',
            description: 'Perform file system operations (read, write, list, etc.)',
            parameters: {
                type: 'object',
                properties: {
                    operation: {
                        type: 'string',
                        enum: ['read', 'write', 'append', 'delete', 'exists', 'list', 'mkdir', 'copy', 'move'],
                        description: 'The file system operation to perform'
                    },
                    path: {
                        type: 'string',
                        description: 'The file or directory path'
                    },
                    content: {
                        type: 'string',
                        description: 'Content to write or append (for write/append operations)'
                    },
                    destination: {
                        type: 'string',
                        description: 'Destination path (for copy/move operations)'
                    },
                    encoding: {
                        type: 'string',
                        description: 'File encoding (default: utf-8)'
                    },
                    recursive: {
                        type: 'boolean',
                        description: 'Whether to operate recursively (for mkdir/delete)'
                    }
                },
                required: ['operation', 'path']
            }
        },
        serverInvocable: true,
        sideEffects: 'write',
        requiresConfirmation: true
    };
    async execute(args, _context) {
        const { operation, path: filePath, content, destination, encoding = 'utf-8', recursive = false } = args;
        try {
            let result;
            switch (operation) {
                case 'read':
                    result = await this.readFile(filePath, encoding);
                    break;
                case 'write':
                    result = await this.writeFile(filePath, content, encoding);
                    break;
                case 'append':
                    result = await this.appendFile(filePath, content, encoding);
                    break;
                case 'delete':
                    result = await this.deleteFile(filePath, recursive);
                    break;
                case 'exists':
                    result = await this.exists(filePath);
                    break;
                case 'list':
                    result = await this.listDirectory(filePath);
                    break;
                case 'mkdir':
                    result = await this.makeDirectory(filePath, recursive);
                    break;
                case 'copy':
                    result = await this.copy(filePath, destination);
                    break;
                case 'move':
                    result = await this.move(filePath, destination);
                    break;
                default:
                    throw new Error(`Unknown operation: ${operation}`);
            }
            return {
                success: true,
                output: result
            };
        }
        catch (error) {
            return {
                success: false,
                error: error.message || 'File system operation failed'
            };
        }
    }
    validateArgs(args) {
        if (!args || typeof args !== 'object')
            return false;
        if (!args.operation || !args.path)
            return false;
        const validOperations = ['read', 'write', 'append', 'delete', 'exists', 'list', 'mkdir', 'copy', 'move'];
        if (!validOperations.includes(args.operation))
            return false;
        if ((args.operation === 'write' || args.operation === 'append') && args.content === undefined) {
            return false;
        }
        if ((args.operation === 'copy' || args.operation === 'move') && !args.destination) {
            return false;
        }
        return true;
    }
    async requestPermission(args, _context) {
        if (!this.requireConfirmation) {
            return true;
        }
        // Read operations don't need confirmation
        if (args.operation === 'read' || args.operation === 'exists' || args.operation === 'list') {
            return true;
        }
        console.log(chalk_1.default.yellow('\n⚠️  File system operation request:'));
        console.log(chalk_1.default.cyan('Operation:'), args.operation);
        console.log(chalk_1.default.cyan('Path:'), args.path);
        if (args.destination) {
            console.log(chalk_1.default.cyan('Destination:'), args.destination);
        }
        if (args.content && args.content.length > 100) {
            console.log(chalk_1.default.cyan('Content:'), args.content.substring(0, 100) + '...');
        }
        else if (args.content) {
            console.log(chalk_1.default.cyan('Content:'), args.content);
        }
        const { confirm } = await inquirer_1.default.prompt([
            {
                type: 'confirm',
                name: 'confirm',
                message: `Do you want to ${args.operation} this file/directory?`,
                default: false
            }
        ]);
        return confirm;
    }
    async readFile(filePath, encoding) {
        const stats = await fs.stat(filePath);
        if (stats.isDirectory()) {
            throw new Error('Cannot read a directory as a file');
        }
        const content = await fs.readFile(filePath, encoding);
        // Truncate if too large
        const maxLength = 50000;
        if (content.length > maxLength) {
            return {
                content: content.substring(0, maxLength),
                truncated: true,
                originalLength: content.length
            };
        }
        return {
            content,
            size: stats.size,
            modified: stats.mtime
        };
    }
    async writeFile(filePath, content, encoding) {
        await fs.writeFile(filePath, content, { encoding: encoding });
        return {
            path: filePath,
            size: Buffer.byteLength(content, encoding),
            operation: 'write'
        };
    }
    async appendFile(filePath, content, encoding) {
        await fs.appendFile(filePath, content, { encoding: encoding });
        return {
            path: filePath,
            appended: content.length,
            operation: 'append'
        };
    }
    async deleteFile(filePath, recursive) {
        const stats = await fs.stat(filePath);
        if (stats.isDirectory() && !recursive) {
            throw new Error('Cannot delete directory without recursive flag');
        }
        if (recursive) {
            await fs.remove(filePath);
        }
        else {
            await fs.unlink(filePath);
        }
        return {
            path: filePath,
            deleted: true,
            wasDirectory: stats.isDirectory()
        };
    }
    async exists(filePath) {
        const exists = await fs.pathExists(filePath);
        if (exists) {
            const stats = await fs.stat(filePath);
            return {
                exists: true,
                isFile: stats.isFile(),
                isDirectory: stats.isDirectory(),
                size: stats.size,
                modified: stats.mtime
            };
        }
        return {
            exists: false
        };
    }
    async listDirectory(dirPath) {
        const stats = await fs.stat(dirPath);
        if (!stats.isDirectory()) {
            throw new Error('Path is not a directory');
        }
        const items = await fs.readdir(dirPath);
        const details = [];
        for (const item of items) {
            const itemPath = path.join(dirPath, item);
            const itemStats = await fs.stat(itemPath);
            details.push({
                name: item,
                type: itemStats.isDirectory() ? 'directory' : 'file',
                size: itemStats.size,
                modified: itemStats.mtime
            });
        }
        return {
            path: dirPath,
            items: details,
            count: details.length
        };
    }
    async makeDirectory(dirPath, recursive) {
        if (recursive) {
            await fs.ensureDir(dirPath);
        }
        else {
            await fs.mkdir(dirPath);
        }
        return {
            path: dirPath,
            created: true,
            recursive
        };
    }
    async copy(source, destination) {
        await fs.copy(source, destination);
        const stats = await fs.stat(destination);
        return {
            source,
            destination,
            size: stats.size,
            operation: 'copy'
        };
    }
    async move(source, destination) {
        await fs.move(source, destination);
        const stats = await fs.stat(destination);
        return {
            source,
            destination,
            size: stats.size,
            operation: 'move'
        };
    }
}
exports.FileSystemTool = FileSystemTool;
//# sourceMappingURL=filesystem.tool.js.map