"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createArgusMCPServer = createArgusMCPServer;
/**
 * Argus MCP Server
 * Exposes TruPulse tools via Model Context Protocol
 */
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
const fetch_1 = require("../../../../fetch");
const envars_1 = require("../../../../envars");
const logger_1 = __importDefault(require("../../../../logger"));
const truPulseTools_1 = require("../tools/truPulseTools");
/**
 * Get base URL for API calls
 * Uses environment variable or defaults to localhost with default port
 */
function getBaseUrl() {
    // Check for environment variable (using process.env directly since it's not in the typed envars)
    const apiUrl = process.env.TWILIO_BASE_URL;
    if (apiUrl) {
        // Remove trailing slash if present
        return apiUrl.replace(/\/$/, '');
    }
    // Default to localhost with default port
    const port = (0, envars_1.getEnvInt)('API_PORT', 15500);
    return `http://localhost:${port}`;
}
/**
 * Base path for TruPulse APIs
 */
const API_PATH = '/api/argus';
/**
 * Helper to call API and handle errors
 */
async function callApi(endpoint, params) {
    try {
        // Build query string from params
        const queryParams = new URLSearchParams();
        // Add projectId and orgId if present
        if (params.projectId) {
            queryParams.append('projectId', params.projectId);
        }
        if (params.orgId) {
            queryParams.append('orgId', params.orgId);
        }
        // Extract applicationId, sessionId, traceId, spanId, includeEvaluationResults, and evalResultsFilters from filters if present
        const filters = params.filters || {};
        const applicationId = params.applicationId || filters.applicationId;
        const sessionId = params.sessionId || filters.sessionId;
        const traceId = params.traceId || filters.traceId;
        const spanId = params.spanId || filters.spanId;
        const includeEvaluationResults = params.includeEvaluationResults === undefined ? filters.includeEvaluationResults : params.includeEvaluationResults;
        const evalResultsFilters = params.evalResultsFilters || filters.evalResultsFilters;
        // Handle different parameter types
        if (params.filters || applicationId || sessionId || traceId || spanId || includeEvaluationResults !== undefined || evalResultsFilters) {
            // Ensure filters object includes all extracted values
            const finalFilters = {
                ...filters,
                ...(applicationId && { applicationId }),
                ...(sessionId && { sessionId }),
                ...(traceId && { traceId }),
                ...(spanId && { spanId }),
                ...(includeEvaluationResults !== undefined && { includeEvaluationResults }),
                ...(evalResultsFilters && { evalResultsFilters }),
            };
            queryParams.append('filters', JSON.stringify(finalFilters));
        }
        if (params.sorting) {
            queryParams.append('sorting', JSON.stringify(params.sorting));
        }
        if (params.limit !== undefined) {
            queryParams.append('limit', String(params.limit));
        }
        if (params.offset !== undefined) {
            queryParams.append('offset', String(params.offset));
        }
        if (traceId) {
            queryParams.append('traceId', traceId);
        }
        if (params.traceIds) {
            queryParams.append('traceIds', Array.isArray(params.traceIds) ? params.traceIds.join(',') : params.traceIds);
        }
        if (spanId) {
            queryParams.append('spanId', spanId);
        }
        if (params.spanIds) {
            queryParams.append('spanIds', Array.isArray(params.spanIds) ? params.spanIds.join(',') : params.spanIds);
        }
        if (params.sessionId) {
            queryParams.append('sessionId', params.sessionId);
        }
        if (params.sessionIds) {
            queryParams.append('sessionIds', Array.isArray(params.sessionIds) ? params.sessionIds.join(',') : params.sessionIds);
        }
        if (params.summaryOnly !== undefined) {
            queryParams.append('summaryOnly', String(params.summaryOnly));
        }
        // Generic extras used by various tools
        if (params.sort) {
            queryParams.append('sort', JSON.stringify(params.sort));
        }
        if (params.page !== undefined) {
            queryParams.append('page', String(params.page));
        }
        if (params.pageSize !== undefined) {
            queryParams.append('pageSize', String(params.pageSize));
        }
        if (params.entity) {
            queryParams.append('entity', String(params.entity));
        }
        if (params.id) {
            queryParams.append('id', String(params.id));
        }
        if (params.group_by) {
            queryParams.append('group_by', String(params.group_by));
        }
        if (params.evaluationId) {
            queryParams.append('evaluationId', String(params.evaluationId));
        }
        if (params.findingId) {
            queryParams.append('findingId', String(params.findingId));
        }
        if (params.timeRange) {
            queryParams.append('timeRange', typeof params.timeRange === 'string' ? params.timeRange : JSON.stringify(params.timeRange));
        }
        if (params.key) {
            queryParams.append('key', String(params.key));
        }
        if (params.prefix) {
            queryParams.append('prefix', String(params.prefix));
        }
        if (params.include) {
            queryParams.append('include', String(params.include));
        }
        if (params.eventName) {
            queryParams.append('eventName', String(params.eventName));
        }
        if (params.query) {
            queryParams.append('query', String(params.query));
        }
        const queryString = queryParams.toString();
        const baseUrl = getBaseUrl();
        const apiUrl = `${baseUrl}${API_PATH}${endpoint}${queryString ? `?${queryString}` : ''}`;
        logger_1.default.debug(`MCP tool calling API: ${apiUrl}`);
        // Use existing fetchWithRetries helper (timeout in ms, retries count)
        const response = await (0, fetch_1.fetchWithRetries)(apiUrl, {
            method: 'GET',
            headers: { 'Content-Type': 'application/json' },
        }, 30000, // 30s timeout
        3);
        const result = await response.json();
        if (!result.success) {
            throw new Error(result.message || 'API call failed');
        }
        return result.data;
    }
    catch (error) {
        logger_1.default.error(`MCP tool API call failed: ${error}`);
        throw error;
    }
}
/**
 * Convert custom tool to MCP tool format
 */
function convertToMCPTool(tool) {
    return {
        name: tool.name,
        description: tool.description,
        inputSchema: {
            type: 'object',
            properties: {
                ...tool.schema.properties,
                projectId: {
                    type: 'string',
                    description: 'Project ID',
                },
                orgId: {
                    type: 'string',
                    description: 'Organization ID',
                },
            },
        },
    };
}
/**
 * Create and configure Argus MCP Server
 */
function createArgusMCPServer() {
    const server = new index_js_1.Server({
        name: 'argus-trupulse-tools',
        version: '1.0.0',
    }, {
        capabilities: {
            tools: {},
        },
    });
    // Get all TruPulse tools
    const truPulseTools = (0, truPulseTools_1.getTruPulseTools)();
    // Handle ListTools request
    server.setRequestHandler(types_js_1.ListToolsRequestSchema, async (request) => {
        return {
            tools: truPulseTools.map(convertToMCPTool),
        };
    });
    // Handle CallTool request
    server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
        const { name, arguments: args } = request.params;
        try {
            let result;
            // Route to appropriate API endpoint based on tool name
            switch (name) {
                // Discovery
                case 'describe_data_model':
                    result = await callApi('/tools/describe-data-model', args);
                    break;
                case 'list_dimensions':
                    result = await callApi('/tools/list-dimensions', args);
                    break;
                case 'get_dimension_values':
                    result = await callApi('/tools/get-dimension-values', args);
                    break;
                // Traces
                case 'get_traces_by_ids':
                    result = await callApi('/tools/get-traces-by-ids', args);
                    break;
                case 'search_traces':
                    result = await callApi('/tools/search-traces', args);
                    break;
                case 'get_trace':
                    result = await callApi('/tools/get-trace', args);
                    break;
                case 'get_trace_span_tree':
                    result = await callApi('/tools/get-trace-span-tree', args);
                    break;
                case 'get_trace_logs':
                    result = await callApi('/tools/get-trace-logs', args);
                    break;
                // Spans
                case 'get_spans_by_ids':
                    result = await callApi('/tools/get-spans-by-ids', args);
                    break;
                case 'search_spans':
                    result = await callApi('/tools/search-spans', args);
                    break;
                case 'get_span':
                    result = await callApi('/tools/get-span', args);
                    break;
                case 'get_span_events':
                    result = await callApi('/tools/get-span-events', args);
                    break;
                case 'get_span_logs':
                    result = await callApi('/tools/get-span-logs', args);
                    break;
                // Sessions
                case 'get_sessions_by_ids':
                    result = await callApi('/tools/get-sessions-by-ids', args);
                    break;
                case 'search_sessions':
                    result = await callApi('/tools/search-sessions', args);
                    break;
                case 'get_session':
                    result = await callApi('/tools/get-session', args);
                    break;
                case 'get_session_traces':
                    result = await callApi('/tools/get-session-traces', args);
                    break;
                case 'get_session_graph':
                    result = await callApi('/tools/get-session-graph', args);
                    break;
                // TruEval tools
                case 'search_evaluations':
                    result = await callApi('/tools/search-evaluations', args);
                    break;
                case 'get_evaluation':
                    result = await callApi('/tools/get-evaluation', args);
                    break;
                case 'get_entity_evaluation_rollup':
                    result = await callApi('/tools/get-entity-evaluation-rollup', args);
                    break;
                // TruScout tools
                case 'search_security_findings':
                    result = await callApi('/tools/search-security-findings', args);
                    break;
                case 'get_security_finding':
                    result = await callApi('/tools/get-security-finding', args);
                    break;
                case 'get_entity_security_rollup':
                    result = await callApi('/tools/get-entity-security-rollup', args);
                    break;
                default:
                    throw new Error(`Unknown tool: ${name}`);
            }
            return {
                content: [
                    {
                        type: 'text',
                        text: JSON.stringify(result),
                    },
                ],
            };
        }
        catch (error) {
            const errorMessage = error instanceof Error ? error.message : String(error);
            logger_1.default.error(`MCP tool execution error for ${name}: ${errorMessage}`);
            return {
                content: [
                    {
                        type: 'text',
                        text: JSON.stringify({
                            error: errorMessage,
                        }),
                    },
                ],
                isError: true,
            };
        }
    });
    return server;
}
//# sourceMappingURL=argusMCPServer.js.map