"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const mablApi_1 = require("@mablhq-internal/runtime/mablApi");
const common_1 = require("../utils/common");
const mcpMablTool_1 = require("./mcpMablTool");
const zod_1 = require("zod");
async function processTestRun(testRun, planRun, mablApiClient, workspaceId, server) {
    if (testRun.status === mablApi_1.TestRun.StatusEnum.Failed &&
        testRun.failure_categorization?.is_failure_category_generated !== true) {
        await server.notification({
            method: 'notifications/message',
            params: {
                level: 'info',
                data: `Analyzing test run ${testRun.id}`,
            },
        });
        const analysis = await mablApiClient.analyzeTestRun(workspaceId, {
            test_run_id: testRun.id,
        });
        testRun.failure_categorization = {
            ...testRun.failure_categorization,
            ...analysis,
        };
    }
    return {
        id: testRun.id,
        testId: testRun.journey?.invariant_id ?? '',
        testName: testRun.journey?.name ?? '',
        failureSummary: testRun.failure_summary,
        failureCategorization: testRun.failure_categorization,
        status: testRun.status,
        statusCause: testRun.status_cause,
        outcome: testRun.outcome,
        applicationId: planRun.applicationId,
        environmentId: planRun.environmentId,
        credentialsId: planRun.credentialsId,
    };
}
const getMablDeployment = (0, mcpMablTool_1.defineTool)({
    schema: {
        name: 'get_mabl_deployment',
        title: 'Get mabl deployment result for last commit',
        description: 'Get mabl deployment result for last commit. This tools is usefull to know if the last commit broke the tests or not and what test failed. Example: Get mabl deployment result for last commit',
        inputSchema: zod_1.z.object({
            commitHash: zod_1.z
                .string()
                .describe('The commit hash to get mabl test run results for'),
            deploymentId: zod_1.z
                .string()
                .describe('The deployment id for the mabl test run results'),
        }),
        type: 'readOnly',
    },
    handle: async (params, context, server) => {
        const { mablApiClient, workspaceId } = context.getCurrentContext();
        if (!params.commitHash && !params.deploymentId) {
            return (0, common_1.stringToToolResult)(`
        ## Instructions
        This tool requires either a commit hash or a deployment ID to get the mabl test run results.
        Find a way to get a commit hash (SHA) from the current git repository or provide a deployment ID.
        If the user is calling this tool it might be because it created a new commit. Do not trust the commit hash from a previous call.
        Call this tool again with either the commit hash or the deployment ID.
        `, true);
        }
        if (params.commitHash && params.deploymentId) {
            return (0, common_1.stringToToolResult)(`
        ## Error
        You can only provide either a commit hash OR a deployment ID, not both.
        Please call this tool again with only one of these parameters.
        `, true);
        }
        await server.notification({
            method: 'notifications/message',
            params: {
                level: 'info',
                data: `Getting deployment events for commit ${params.commitHash}`,
            },
        });
        let deploymentEvents;
        if (params.commitHash) {
            deploymentEvents = (await mablApiClient.getDeploymentEventsByRevision(workspaceId, params.commitHash)).map((event) => ({
                id: event.id,
                applicationId: event.application_id,
                environmentId: event.environment_id,
            }));
        }
        else {
            const deploymentEvent = await mablApiClient.getDeploymentEvent(params.deploymentId);
            deploymentEvents = [
                {
                    id: deploymentEvent.id,
                    applicationId: deploymentEvent.application_id,
                    environmentId: deploymentEvent.environment_id,
                },
            ];
        }
        const planRuns = (await Promise.all(deploymentEvents.map(async (event) => {
            await server.notification({
                method: 'notifications/message',
                params: {
                    level: 'info',
                    data: `Getting plan runs for deployment event ${event.id}`,
                },
            });
            const result = await mablApiClient.getPlanRunsByDeploymentEventId(event.id);
            return (result.run_policy_executions?.map((planRun) => ({
                id: planRun.id,
                status: planRun.status,
                statusCause: planRun.status_cause,
                applicationId: event.applicationId,
                environmentId: event.environmentId,
                credentialsId: planRun.run_policy?.credentials_id,
            })) || []);
        }))).flat();
        const testRuns = (await Promise.all(planRuns.map(async (planRun) => {
            await server.notification({
                method: 'notifications/message',
                params: {
                    level: 'info',
                    data: `Getting test runs for plan run ${planRun.id}`,
                },
            });
            const result = await mablApiClient.getTestRunsByPlanRunId(planRun.id);
            const testScriptExecutions = result.test_script_executions || [];
            return Promise.all(testScriptExecutions.map((testRun) => processTestRun(testRun, planRun, mablApiClient, workspaceId, server)));
        }))).flat();
        return {
            content: [
                {
                    type: 'text',
                    text: `
          # Instructions
          You are going to get the result of the last commit in mabl.
          The result is a list of deployment events, plan runs, and test runs.
          The deployment events are the events that were triggered by the commit.
          The plan runs are the plan runs that were triggered by the deployment events.
          The test runs are the test runs that were triggered by the plan runs.
          What's important here is to the number of test runs that failed. It's also important to inform the tests that passed.
          The tests runs have information about the id, the envinoment, the application and credentials. 
          You are going to need those if the user wants to run the test locally.
          The user might want to override the credentials or de environment to run the test locally.

          # Result
          Deployment events:
          ${(0, common_1.jsonPrettyPrint)(deploymentEvents)}
          Plan runs:
          ${(0, common_1.jsonPrettyPrint)(planRuns)}
          Test runs:
          ${(0, common_1.jsonPrettyPrint)(testRuns)}
          `,
                },
            ],
        };
    },
});
exports.default = [getMablDeployment];
