"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const zod_1 = require("zod");
const mcpMablTool_1 = require("./mcpMablTool");
const mablApi_1 = require("@mablhq-internal/runtime/mablApi");
const featureSet_1 = require("@mablhq-internal/runtime/api/featureSet");
const common_1 = require("../utils/common");
const planNewTest = (0, mcpMablTool_1.defineTool)({
    schema: {
        name: 'plan_new_test',
        title: 'Plan a new test',
        description: 'Plan a new test. Example: Plan a new test based on these details.',
        inputSchema: zod_1.z.object({
            originalIntent: zod_1.z.string().describe(`The intent of the test.
          Be as detailed as possible.
          If you are given a ticket, provide the intent based on the ticket.
          If you are not working on a ticket, provide the intent based on the changes you made to the code.
      `),
            issueOrTicket: zod_1.z
                .string()
                .describe('The issue or ticket description that is being worked on. This will be used to generate the intent.')
                .optional(),
            requestedChanges: zod_1.z
                .string()
                .describe('The user requested changes to the test plan. When the user requests changes, set this to the changes needed.')
                .optional(),
        }),
        type: 'readOnly',
    },
    handle: async (params, context) => {
        const { originalIntent, requestedChanges, issueOrTicket } = params;
        const { mablApiClient, workspaceId, planHistory } = context.getCurrentContext();
        if (!context.featureIsAvailable(featureSet_1.GENERATIVE_AI_FEATURE_FLAG)) {
            return (0, common_1.stringToToolResult)('Generative AI is not available for your account. Please contact your workspace owner or mabl support for assistance in activating this feature.', true);
        }
        if (!requestedChanges) {
            planHistory.reset();
        }
        let fullIntent = originalIntent;
        if (issueOrTicket) {
            fullIntent += `\n\nIssue or ticket: ${issueOrTicket}`;
        }
        planHistory.addToChatHistory({
            role: mablApi_1.ChatMessageRoleEnum.User,
            message: requestedChanges || fullIntent,
            timestamp: Date.now(),
        });
        const { lastArtifact, chatHistory, generationReferences, trainingSessionId } = planHistory.getPlanHistoryState();
        const artifact = lastArtifact ?? {
            test_metadata: {
                name: '',
                description: '',
                test_case: '',
            },
            version: 0,
            timestamp: Date.now(),
        };
        const prePlanResponse = await mablApiClient.generateTestPlan({
            workspaceId,
            messages: chatHistory,
            artifact,
            generationReferences,
            trainingSessionId,
        });
        planHistory.setLastArtifact(prePlanResponse.artifact);
        planHistory.setGenerationReferences(prePlanResponse.generation_references);
        planHistory.addToChatHistory(prePlanResponse.message ?? {
            role: mablApi_1.ChatMessageRoleEnum.Model,
            message: '',
            timestamp: Date.now(),
        });
        const { application_id: applicationId, environment_id: environmentId, credentials_id: credentialsId, deployment_id: deploymentId, } = prePlanResponse?.artifact?.test_information ?? {};
        const [application, environment, credentials, deployment] = await Promise.all([
            applicationId ? mablApiClient.getApplication(applicationId) : undefined,
            environmentId ? mablApiClient.getEnvironment(environmentId) : undefined,
            credentialsId ? mablApiClient.getCredential(credentialsId) : undefined,
            deploymentId
                ? mablApiClient.getDeploymentEntity(deploymentId)
                : undefined,
        ]);
        const newArtifact = prePlanResponse.artifact;
        return {
            content: [
                {
                    type: 'text',
                    text: `
            ## Instructions
            You MUST present the response to the user in EXACTLY the format specified below. Follow these rules strictly:
            1. Show the user the response using the EXACT format template provided below
            2. Do NOT paraphrase, summarize, or reformat the output
            3. Skip any fields that are null, undefined, or empty - do not show them to the user
            4. After showing the formatted response, ask the user if there are any changes needed to the test plan, or if the plan is good and they want to build the test
            5. If the user needs changes, call #plan_new_test again with the requestedChanges parameter
            6. If the user wants to build the test, call #create_mabl_test_from_plan

            ## Required Output Format
            Present the following EXACTLY as shown:

            # Summary
            Test case: ${newArtifact?.test_information?.test_case || ''}
            Test name: ${newArtifact?.test_information?.name || ''}
            Test description: ${newArtifact?.test_information?.description || ''}
            Test application: ${application?.name || ''}
            Test environment: ${environment?.name || ''}
            URL: ${newArtifact?.test_information?.url_override ||
                        deployment?.uri ||
                        'No url selected'}
            Test credentials: ${credentials?.name || ''}

            # Test Plan
            Implementation notes:
            ${newArtifact?.agent_state?.entireTestPlan?.implementation_notes ||
                        ''}

            Tasks:
            ${newArtifact?.agent_state?.entireTestPlan?.tasks
                        ?.map((task, index) => `
            ${index + 1}. ${task.task}
              Validation: ${task.suggested_validation}
              Suggested flows: ${task.suggested_flow_options
                        ?.map((flow) => `
                  - ${flow.flow_name}: ${flow.reasoning}`)
                        .join('') || 'None'}
              Suggested snippets: ${task.suggested_snippet_options
                        ?.map((snippet) => `
                  - ${snippet.snippet_name}: ${snippet.reasoning}`)
                        .join('') || 'None'}
            `)
                        .join('\n') || 'No tasks defined'}

            ## Additional Context
            The structured artifact data is available if the user asks for more specific details about the test plan.
          `,
                },
            ],
            structuredContent: newArtifact,
        };
    },
});
exports.default = [planNewTest];
