"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 });
/*
 * MCP audit-log inbound channel provenance — camunda/camunda#56234
 * (SC-AUD-01/02/03).
 */
const _8_10_1 = require("../../../../fixtures/8.10");
const test_1 = require("@playwright/test");
const apiHelpers_1 = require("../../../../utils/apiHelpers");
const mcpHelpers_1 = require("../../../../utils/mcpHelpers");
const constants_1 = require("../../../../utils/constants");
// Raw BPMN `io.camunda.tool:name` annotation — what the audit log stores in
// inboundChannelToolName (not the composite tools/list name).
const TOOL_NAME_RAW = 'mcp-as-tool-process';
const MCP_PROCESS_DEFINITION_ID = 'mcpAsToolProcess';
let authToken;
let mcpProcessesUrl;
let messageSubscriptionsSearchUrl;
let auditLogsSearchUrl;
let mcpSessionId = null;
let restProcessDefinitionKey;
let compositeToolName;
_8_10_1.test.describe.configure({ mode: 'parallel' });
_8_10_1.test.describe('Orchestration Cluster MCP Server — audit log inbound channel', () => {
    _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');
        auditLogsSearchUrl = (0, apiHelpers_1.buildZeebeApiUrl)('/v2/audit-logs/search', 'saas', 'agentic_cluster');
        const apiContext = await (0, apiHelpers_1.getApiRequestContext)();
        mcpSessionId = await (0, mcpHelpers_1.initializeMcpSession)(apiContext, mcpProcessesUrl, authToken, mcpSessionId);
        const [mcpKey, restKey] = 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_process_instance_test_file.bpmn', authToken, 'saas', 'agentic_cluster'),
        ]);
        if (mcpKey == null) {
            throw new Error('Failed to deploy mcp_as_tool_process.bpmn');
        }
        if (restKey == null) {
            throw new Error('Failed to deploy mcp_process_instance_test_file.bpmn');
        }
        restProcessDefinitionKey = String(restKey);
        // Composite tool name is `<toolName>_<messageSubscriptionKey>`.
        await (0, test_1.expect)(async () => {
            const res = await apiContext.post(messageSubscriptionsSearchUrl, {
                headers: (0, mcpHelpers_1.buildMcpHeaders)(authToken, mcpSessionId),
                data: {
                    filter: {
                        processDefinitionId: MCP_PROCESS_DEFINITION_ID,
                        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);
            compositeToolName = `${TOOL_NAME_RAW}_${json.items[0].messageSubscriptionKey}`;
        }).toPass(constants_1.deletionAssertionOptions);
    });
    (0, _8_10_1.test)('SC-AUD-01 — MCP tools/call produces audit entry with inboundChannelType=MCP', async () => {
        const apiContext = await (0, apiHelpers_1.getApiRequestContext)();
        const callBody = await (0, mcpHelpers_1.callTool)(apiContext, mcpProcessesUrl, authToken, mcpSessionId, compositeToolName, {});
        (0, test_1.expect)(callBody.result).toBeDefined();
        (0, test_1.expect)(callBody.result.isError).not.toBe(true);
        const pik = (0, mcpHelpers_1.extractProcessInstanceKey)(callBody.result.content[0]?.text ?? '');
        (0, test_1.expect)(pik, 'Expected processInstanceKey from MCP tools/call').not.toBeNull();
        await (0, test_1.expect)(async () => {
            const res = await apiContext.post(auditLogsSearchUrl, {
                headers: (0, mcpHelpers_1.buildMcpHeaders)(authToken, mcpSessionId),
                data: {
                    filter: {
                        processInstanceKey: pik,
                        operationType: 'CREATE',
                    },
                    page: { limit: 10 },
                },
            });
            await (0, mcpHelpers_1.assertResponseStatus)(res, 200);
            const json = (await res.json());
            const entry = json.items.find((i) => i.entityType === 'PROCESS_INSTANCE');
            (0, test_1.expect)(entry, `Expected a PROCESS_INSTANCE CREATE audit entry for pik ${pik}`).toBeDefined();
            (0, test_1.expect)(entry.inboundChannelType).toBe('MCP');
        }).toPass(constants_1.auditLogAssertionOptions);
    });
    (0, _8_10_1.test)('SC-AUD-02 — MCP audit entry captures the raw tool name in inboundChannelToolName', async () => {
        const apiContext = await (0, apiHelpers_1.getApiRequestContext)();
        const callBody = await (0, mcpHelpers_1.callTool)(apiContext, mcpProcessesUrl, authToken, mcpSessionId, compositeToolName, {});
        (0, test_1.expect)(callBody.result).toBeDefined();
        (0, test_1.expect)(callBody.result.isError).not.toBe(true);
        const pik = (0, mcpHelpers_1.extractProcessInstanceKey)(callBody.result.content[0]?.text ?? '');
        (0, test_1.expect)(pik).not.toBeNull();
        await (0, test_1.expect)(async () => {
            const res = await apiContext.post(auditLogsSearchUrl, {
                headers: (0, mcpHelpers_1.buildMcpHeaders)(authToken, mcpSessionId),
                data: {
                    filter: {
                        processInstanceKey: pik,
                        operationType: 'CREATE',
                    },
                    page: { limit: 10 },
                },
            });
            await (0, mcpHelpers_1.assertResponseStatus)(res, 200);
            const json = (await res.json());
            const entry = json.items.find((i) => i.entityType === 'PROCESS_INSTANCE');
            (0, test_1.expect)(entry, `Expected a PROCESS_INSTANCE CREATE audit entry for pik ${pik}`).toBeDefined();
            // Raw annotation value, not the composite tools/list name.
            (0, test_1.expect)(entry.inboundChannelToolName).toBe(TOOL_NAME_RAW);
            (0, test_1.expect)(entry.inboundChannelType).toBe('MCP');
        }).toPass(constants_1.auditLogAssertionOptions);
    });
    (0, _8_10_1.test)('SC-AUD-03 — REST-triggered start is distinguishable from MCP (inboundChannelType and tool name both null)', async () => {
        const apiContext = await (0, apiHelpers_1.getApiRequestContext)();
        // NONE-start BPMN started via REST — bypasses MCP entirely.
        const restPik = await (0, apiHelpers_1.createProcessInstance)(restProcessDefinitionKey, authToken, 'saas', 'agentic_cluster');
        (0, test_1.expect)(restPik).toBeTruthy();
        await (0, test_1.expect)(async () => {
            const res = await apiContext.post(auditLogsSearchUrl, {
                headers: (0, mcpHelpers_1.buildMcpHeaders)(authToken, mcpSessionId),
                data: {
                    filter: {
                        processInstanceKey: restPik,
                        operationType: 'CREATE',
                    },
                    page: { limit: 10 },
                },
            });
            await (0, mcpHelpers_1.assertResponseStatus)(res, 200);
            const json = (await res.json());
            const entry = json.items.find((i) => i.entityType === 'PROCESS_INSTANCE');
            (0, test_1.expect)(entry, `Expected a PROCESS_INSTANCE CREATE audit entry for REST pik ${restPik}`).toBeDefined();
            // REST-triggered entries have both fields null (verified on 8.10-SNAPSHOT).
            (0, test_1.expect)(entry.inboundChannelType).toBeNull();
            (0, test_1.expect)(entry.inboundChannelToolName).toBeNull();
        }).toPass(constants_1.auditLogAssertionOptions);
    });
});
