"use strict";
/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
 * one or more contributor license agreements. See the NOTICE file distributed
 * with this work for additional information regarding copyright ownership.
 * Licensed under the Camunda License 1.0. You may not use this file
 * except in compliance with the Camunda License 1.0.
 */
Object.defineProperty(exports, "__esModule", { value: true });
/*
 * Tests for POST /mcp/processes — tools/call endpoint.
 * Direct JSON-RPC 2.0 calls; no browser interaction.
 */
const _8_10_1 = require("../../../../fixtures/8.10");
const test_1 = require("@playwright/test");
const apiHelpers_1 = require("../../../../utils/apiHelpers");
const constants_1 = require("../../../../utils/constants");
const mcpHelpers_1 = require("../../../../utils/mcpHelpers");
let authToken;
let mcpProcessesUrl;
let messageSubscriptionsSearchUrl;
let processInstancesSearchUrl;
let variablesSearchUrl;
let mcpSessionId = null;
// processInstanceKey of a pre-created instance used by SC-CALL-08 (getProcessInstance smoke).
let smokeProcessInstanceKey = null;
_8_10_1.test.describe.configure({ mode: 'parallel' });
_8_10_1.test.describe('Orchestration Cluster MCP Server — /mcp/processes tools/call', () => {
    _8_10_1.test.beforeAll(async () => {
        authToken = await (0, apiHelpers_1.authSaasAPI)(undefined, 'agentic_cluster');
        mcpProcessesUrl = (0, apiHelpers_1.buildZeebeApiUrl)('/mcp/processes', 'saas', 'agentic_cluster');
        messageSubscriptionsSearchUrl = (0, apiHelpers_1.buildZeebeApiUrl)('/v2/message-subscriptions/search', 'saas', 'agentic_cluster');
        processInstancesSearchUrl = (0, apiHelpers_1.buildZeebeApiUrl)('/v2/process-instances/search', 'saas', 'agentic_cluster');
        variablesSearchUrl = (0, apiHelpers_1.buildZeebeApiUrl)('/v2/variables/search', 'saas', 'agentic_cluster');
        const apiContext = await (0, apiHelpers_1.getApiRequestContext)();
        mcpSessionId = await (0, mcpHelpers_1.initializeMcpSession)(apiContext, mcpProcessesUrl, authToken, mcpSessionId);
        // Deploy processes needed by this suite concurrently.
        const [toolProcessKey, withInputsKey] = await Promise.all([
            (0, apiHelpers_1.deployProcess)('./resources/mcp_server_saas/mcp_as_tool_process.bpmn', authToken, 'saas', 'agentic_cluster'),
            (0, apiHelpers_1.deployProcess)('./resources/mcp_server_saas/mcp_as_tool_with_inputs.bpmn', authToken, 'saas', 'agentic_cluster'),
        ]);
        if (toolProcessKey == null)
            throw new Error('Failed to deploy mcp_as_tool_process.bpmn');
        if (withInputsKey == null)
            throw new Error('Failed to deploy mcp_as_tool_with_inputs.bpmn');
        // Pre-create a process instance for SC-CALL-08 (getProcessInstance smoke).
        const restRes = await apiContext.post((0, apiHelpers_1.buildZeebeApiUrl)('/v2/process-instances', 'saas', 'agentic_cluster'), {
            headers: (0, mcpHelpers_1.buildMcpHeaders)(authToken, mcpSessionId),
            data: { processDefinitionId: 'mcpAsToolProcess', variables: {} },
        });
        if (restRes.ok()) {
            const body = (await restRes.json());
            smokeProcessInstanceKey = body.processInstanceKey
                ? String(body.processInstanceKey)
                : null;
        }
    });
    (0, _8_10_1.test)('SC-CALL-01 — Tool invocation starts a process instance', async () => {
        const apiContext = await (0, apiHelpers_1.getApiRequestContext)();
        let toolName = null;
        await _8_10_1.test.step('Resolve latest subscription key for mcpAsToolProcess', async () => {
            await (0, test_1.expect)(async () => {
                const res = await apiContext.post(messageSubscriptionsSearchUrl, {
                    headers: (0, mcpHelpers_1.buildMcpHeaders)(authToken, mcpSessionId),
                    data: {
                        filter: {
                            processDefinitionId: 'mcpAsToolProcess',
                            messageSubscriptionType: 'START_EVENT',
                        },
                        sort: [{ field: 'processDefinitionVersion', order: 'desc' }],
                        page: { limit: 1 },
                    },
                });
                await (0, mcpHelpers_1.assertResponseStatus)(res, 200);
                const json = (await res.json());
                (0, test_1.expect)(json.items.length).toBeGreaterThanOrEqual(1);
                toolName = `mcp-as-tool-process_${json.items[0].messageSubscriptionKey}`;
            }).toPass(constants_1.defaultAssertionOptions);
        });
        await _8_10_1.test.step('Invoke tool and assert processInstanceKey returned', async () => {
            const body = await (0, mcpHelpers_1.callTool)(apiContext, mcpProcessesUrl, authToken, mcpSessionId, toolName, {});
            (0, test_1.expect)(body.result).toBeDefined();
            (0, test_1.expect)(body.result.isError).not.toBe(true);
            const text = body.result.content[0]?.text ?? '';
            const processInstanceKey = (0, mcpHelpers_1.extractProcessInstanceKey)(text);
            (0, test_1.expect)(processInstanceKey, `Expected a numeric processInstanceKey in tool result, got: ${text}`).not.toBeNull();
        });
    });
    (0, _8_10_1.test)('SC-CALL-02 — Tool arguments become process variables', async () => {
        const apiContext = await (0, apiHelpers_1.getApiRequestContext)();
        let toolName = null;
        let processInstanceKey = null;
        await _8_10_1.test.step('Resolve latest subscription key for mcpAsToolWithInputs', async () => {
            await (0, test_1.expect)(async () => {
                const res = await apiContext.post(messageSubscriptionsSearchUrl, {
                    headers: (0, mcpHelpers_1.buildMcpHeaders)(authToken, mcpSessionId),
                    data: {
                        filter: {
                            processDefinitionId: 'mcpAsToolWithInputs',
                            messageSubscriptionType: 'START_EVENT',
                        },
                        sort: [{ field: 'processDefinitionVersion', order: 'desc' }],
                        page: { limit: 1 },
                    },
                });
                await (0, mcpHelpers_1.assertResponseStatus)(res, 200);
                const json = (await res.json());
                (0, test_1.expect)(json.items.length).toBeGreaterThanOrEqual(1);
                toolName = `mcp-as-tool-with-inputs_${json.items[0].messageSubscriptionKey}`;
            }).toPass(constants_1.defaultAssertionOptions);
        });
        await _8_10_1.test.step('Invoke tool with arguments', async () => {
            const body = await (0, mcpHelpers_1.callTool)(apiContext, mcpProcessesUrl, authToken, mcpSessionId, toolName, { firstName: 'TestUser', amount: 42 });
            (0, test_1.expect)(body.result).toBeDefined();
            (0, test_1.expect)(body.result.isError).not.toBe(true);
            const text = body.result.content[0]?.text ?? '';
            processInstanceKey = (0, mcpHelpers_1.extractProcessInstanceKey)(text);
            (0, test_1.expect)(processInstanceKey).not.toBeNull();
        });
        await _8_10_1.test.step('Verify tool arguments visible as process variables', async () => {
            await (0, test_1.expect)(async () => {
                const varRes = await apiContext.post(variablesSearchUrl, {
                    headers: (0, mcpHelpers_1.buildMcpHeaders)(authToken, mcpSessionId),
                    data: { filter: { processInstanceKey }, page: { limit: 50 } },
                });
                await (0, mcpHelpers_1.assertResponseStatus)(varRes, 200);
                const varJson = (await varRes.json());
                const varMap = Object.fromEntries(varJson.items.map((v) => [v.name, v.value]));
                (0, test_1.expect)(varMap['firstName']).toBe('"TestUser"');
                (0, test_1.expect)(varMap['amount']).toBe('42');
            }).toPass(constants_1.defaultAssertionOptions);
        });
    });
    (0, _8_10_1.test)('SC-CALL-05 — Calling a non-existent tool returns an error', async () => {
        const apiContext = await (0, apiHelpers_1.getApiRequestContext)();
        const body = await (0, mcpHelpers_1.callTool)(apiContext, mcpProcessesUrl, authToken, mcpSessionId, 'non-existent-tool_000', {});
        const hasJsonRpcError = body.error != null;
        const hasMcpError = body.result?.isError === true;
        (0, test_1.expect)(hasJsonRpcError || hasMcpError, `Expected an error for unknown tool, got: ${JSON.stringify(body)}`).toBe(true);
    });
    (0, _8_10_1.test)('SC-CALL-06 — Calling a stale tool after redeployment without annotation returns an error', async () => {
        const apiContext = await (0, apiHelpers_1.getApiRequestContext)();
        let staleToolName = null;
        await _8_10_1.test.step('Deploy stale process with MCP annotation', async () => {
            const staleKey = await (0, apiHelpers_1.deployProcess)('./resources/mcp_server_saas/mcp_as_tool_call_stale.bpmn', authToken, 'saas', 'agentic_cluster');
            if (staleKey == null)
                throw new Error('Failed to deploy mcp_as_tool_call_stale.bpmn');
        });
        await _8_10_1.test.step('Wait for stale tool to appear in tools/list', async () => {
            await (0, test_1.expect)(async () => {
                const tools = await (0, mcpHelpers_1.listTools)(apiContext, mcpProcessesUrl, authToken, mcpSessionId);
                const match = tools.find((t) => /^mcp-call-stale_\d+$/.test(t.name));
                (0, test_1.expect)(match).toBeDefined();
                staleToolName = match.name;
            }).toPass(constants_1.defaultAssertionOptions);
        });
        await _8_10_1.test.step('Redeploy without MCP annotation', async () => {
            const disabledKey = await (0, apiHelpers_1.deployProcess)('./resources/mcp_server_saas/mcp_as_tool_call_stale_disabled.bpmn', authToken, 'saas', 'agentic_cluster');
            if (disabledKey == null)
                throw new Error('Failed to deploy mcp_as_tool_call_stale_disabled.bpmn');
        });
        await _8_10_1.test.step('Wait for stale tool to disappear from tools/list', async () => {
            await (0, test_1.expect)(async () => {
                const tools = await (0, mcpHelpers_1.listTools)(apiContext, mcpProcessesUrl, authToken, mcpSessionId);
                (0, test_1.expect)(tools.some((t) => /^mcp-call-stale_\d+$/.test(t.name))).toBe(false);
            }).toPass(constants_1.deletionAssertionOptions);
        });
        await _8_10_1.test.step('Invoke stale tool name and assert error', async () => {
            const body = await (0, mcpHelpers_1.callTool)(apiContext, mcpProcessesUrl, authToken, mcpSessionId, staleToolName, {});
            const hasJsonRpcError = body.error != null;
            const hasMcpError = body.result?.isError === true;
            (0, test_1.expect)(hasJsonRpcError || hasMcpError, `Expected an error invoking stale tool ${staleToolName}, got: ${JSON.stringify(body)}`).toBe(true);
        });
    });
    (0, _8_10_1.test)('SC-CALL-08 — getProcessInstance static tool is accessible on /mcp/processes', async () => {
        const apiContext = await (0, apiHelpers_1.getApiRequestContext)();
        let instanceKey = smokeProcessInstanceKey;
        await _8_10_1.test.step('Resolve process instance key', async () => {
            if (!instanceKey) {
                // Attempt to find any mcpAsToolProcess instance via the search API.
                const searchRes = await apiContext.post(processInstancesSearchUrl, {
                    headers: (0, mcpHelpers_1.buildMcpHeaders)(authToken, mcpSessionId),
                    data: {
                        filter: { processDefinitionId: 'mcpAsToolProcess' },
                        sort: [{ field: 'processInstanceKey', order: 'desc' }],
                        page: { limit: 1 },
                    },
                });
                if (searchRes.ok()) {
                    const searchJson = (await searchRes.json());
                    instanceKey = searchJson.items[0]?.processInstanceKey ?? null;
                }
            }
            (0, test_1.expect)(instanceKey, 'No mcpAsToolProcess instance available for getProcessInstance smoke test').not.toBeNull();
        });
        await _8_10_1.test.step('Call getProcessInstance tool and verify response', async () => {
            const body = await (0, mcpHelpers_1.callTool)(apiContext, mcpProcessesUrl, authToken, mcpSessionId, 'getProcessInstance', { processInstanceKey: instanceKey });
            (0, test_1.expect)(body.result).toBeDefined();
            (0, test_1.expect)(body.result.isError).not.toBe(true);
            const text = body.result.content[0]?.text ?? '';
            (0, test_1.expect)(text).toContain(instanceKey);
            (0, test_1.expect)(text.toLowerCase()).toMatch(/state|status/);
        });
    });
});
