/**
 * Tools Routes
 *
 * Handles tool listing and execution API endpoints.
 */
import { Router } from 'express';
import { requireScope, asyncHandler, ApiServerError } from '../middleware/index.js';
// Lazy load the tool registry
let toolRegistryInstance = null;
async function getToolRegistry() {
    if (!toolRegistryInstance) {
        const { ToolRegistry } = await import('../../tools/registry.js');
        toolRegistryInstance = ToolRegistry.getInstance();
    }
    return toolRegistryInstance;
}
// Lazy load the agent for tool execution
let agentInstance = null;
async function getAgent() {
    if (!agentInstance) {
        const { CodeBuddyAgent } = await import('../../agent/codebuddy-agent.js');
        agentInstance = new CodeBuddyAgent(process.env.GROK_API_KEY || '', process.env.GROK_BASE_URL, process.env.GROK_MODEL || 'grok-3-latest');
    }
    return agentInstance;
}
const router = Router();
/**
 * GET /api/tools
 * List all available tools
 */
router.get('/', requireScope('tools'), asyncHandler(async (req, res) => {
    const registry = await getToolRegistry();
    const tools = registry.getAllTools();
    const toolInfos = tools.map((tool) => ({
        name: tool.name,
        description: tool.description || '',
        category: tool.category || 'general',
        parameters: tool.parameters || {},
        requiresConfirmation: tool.requiresConfirmation || false,
        isDestructive: tool.isDestructive || false,
    }));
    res.json({
        tools: toolInfos,
        total: toolInfos.length,
    });
}));
/**
 * GET /api/tools/:name
 * Get details for a specific tool
 */
router.get('/:name', requireScope('tools'), asyncHandler(async (req, res) => {
    const name = req.params.name;
    const registry = await getToolRegistry();
    const tool = registry.getTool(name);
    if (!tool) {
        throw ApiServerError.notFound(`Tool '${name}'`);
    }
    const toolInfo = {
        name: tool.name,
        description: tool.description || '',
        category: tool.category || 'general',
        parameters: tool.parameters || {},
        requiresConfirmation: tool.requiresConfirmation || false,
        isDestructive: tool.isDestructive || false,
    };
    res.json(toolInfo);
}));
/**
 * POST /api/tools/:name/execute
 * Execute a specific tool
 */
router.post('/:name/execute', requireScope('tools:execute'), asyncHandler(async (req, res) => {
    const startTime = Date.now();
    const name = req.params.name;
    const body = req.body;
    // Require tools:execute scope or admin
    if (!req.auth?.scopes.includes('tools:execute') && !req.auth?.scopes.includes('admin')) {
        throw ApiServerError.forbidden('Tool execution requires tools:execute scope');
    }
    const registry = await getToolRegistry();
    const tool = registry.getTool(name);
    if (!tool) {
        throw ApiServerError.notFound(`Tool '${name}'`);
    }
    // Check if tool requires confirmation and it wasn't provided
    if (tool.requiresConfirmation && !body.confirmed) {
        res.status(200).json({
            toolName: name,
            success: false,
            requiresConfirmation: true,
            confirmationMessage: `Tool '${name}' requires confirmation. Set confirmed=true to execute.`,
            executionTime: Date.now() - startTime,
        });
        return;
    }
    try {
        const agent = await getAgent();
        const result = await agent.executeTool(name, body.parameters || {});
        const response = {
            toolName: name,
            success: result.success,
            output: result.output,
            error: result.error,
            executionTime: Date.now() - startTime,
        };
        res.json(response);
    }
    catch (error) {
        const message = error instanceof Error ? error.message : 'Unknown error';
        const response = {
            toolName: name,
            success: false,
            error: message,
            executionTime: Date.now() - startTime,
        };
        res.status(500).json(response);
    }
}));
/**
 * GET /api/tools/categories
 * List tool categories
 */
router.get('/categories', requireScope('tools'), asyncHandler(async (req, res) => {
    const registry = await getToolRegistry();
    const tools = registry.getAllTools();
    const categories = new Map();
    for (const tool of tools) {
        const category = tool.category || 'general';
        categories.set(category, (categories.get(category) || 0) + 1);
    }
    res.json({
        categories: Object.fromEntries(categories),
    });
}));
/**
 * POST /api/tools/batch
 * Execute multiple tools in sequence
 */
router.post('/batch', requireScope('tools:execute'), asyncHandler(async (req, res) => {
    const startTime = Date.now();
    const { tools } = req.body;
    if (!Array.isArray(tools) || tools.length === 0) {
        throw ApiServerError.badRequest('Tools must be a non-empty array');
    }
    if (tools.length > 10) {
        throw ApiServerError.badRequest('Maximum 10 tools per batch');
    }
    const registry = await getToolRegistry();
    const agent = await getAgent();
    const results = [];
    for (const toolRequest of tools) {
        const toolStartTime = Date.now();
        const tool = registry.getTool(toolRequest.name);
        if (!tool) {
            results.push({
                toolName: toolRequest.name,
                success: false,
                error: `Tool '${toolRequest.name}' not found`,
                executionTime: Date.now() - toolStartTime,
            });
            continue;
        }
        // Skip tools requiring confirmation in batch mode
        if (tool.requiresConfirmation) {
            results.push({
                toolName: toolRequest.name,
                success: false,
                error: 'Tool requires confirmation and cannot be executed in batch mode',
                requiresConfirmation: true,
                executionTime: Date.now() - toolStartTime,
            });
            continue;
        }
        try {
            const result = await agent.executeTool(toolRequest.name, toolRequest.parameters || {});
            results.push({
                toolName: toolRequest.name,
                success: result.success,
                output: result.output,
                error: result.error,
                executionTime: Date.now() - toolStartTime,
            });
        }
        catch (error) {
            const message = error instanceof Error ? error.message : 'Unknown error';
            results.push({
                toolName: toolRequest.name,
                success: false,
                error: message,
                executionTime: Date.now() - toolStartTime,
            });
        }
    }
    res.json({
        results,
        totalExecutionTime: Date.now() - startTime,
        successCount: results.filter((r) => r.success).length,
        failureCount: results.filter((r) => !r.success).length,
    });
}));
export default router;
//# sourceMappingURL=tools.js.map