"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.initiateAuthoringSession = initiateAuthoringSession;
exports.loadAuthoringSession = loadAuthoringSession;
exports.getInlineArtifactByName = getInlineArtifactByName;
exports.getJsonFromInlineArtifact = getJsonFromInlineArtifact;
exports.extractTestIdFromArtifacts = extractTestIdFromArtifacts;
const uuid_1 = require("uuid");
const mablApi_1 = require("../../mablApi");
const constants_1 = require("../../core/constants");
const flowResolver_1 = require("../../util/flowResolver");
async function initiateAuthoringSession(apiClient, params) {
    const initialPlanningMessage = [
        `Create a test for: ${params.testIntent}`,
        params.applicationId
            ? `Use the application with ID: ${params.applicationId}`
            : '',
    ].join('\n');
    const planningSessionResponse = await apiClient.generateTestPlan({
        workspaceId: params.workspaceId,
        messages: [
            {
                role: mablApi_1.ChatMessageRoleEnum.User,
                message: initialPlanningMessage,
                timestamp: Date.now(),
            },
        ],
        artifact: {
            version: 0,
            timestamp: Date.now(),
        },
        generationReferences: {},
        trainingSessionId: params.trainingSessionId,
    });
    const planningArtifacts = [];
    const testInformation = planningSessionResponse.artifact.test_information;
    if (testInformation) {
        planningArtifacts.push({
            id: (0, uuid_1.v4)(),
            description: 'Test information',
            artifact_type: 'inline',
            name: 'test_information',
            artifact_data: {
                type: 'json',
                value: testInformation,
            },
        });
    }
    const testOutline = planningSessionResponse.artifact.agent_state?.entireTestPlan;
    if (testOutline) {
        planningArtifacts.push({
            id: (0, uuid_1.v4)(),
            description: 'Test outline',
            artifact_type: 'inline',
            name: 'test_outline',
            artifact_data: {
                type: 'json',
                value: testOutline,
            },
        });
    }
    const request = {
        is_cloud: false,
        planning_artifacts: planningArtifacts,
        planning_messages: planningSessionResponse.messages,
        application_id: params.applicationId,
    };
    const response = await apiClient.initiateTestAuthoringSession(params.workspaceId, request);
    return {
        sessionId: response.session_id,
        url: params.url,
        testIntent: params.testIntent,
        workspaceId: params.workspaceId,
        applicationId: params.applicationId,
        testName: testInformation?.name,
        testDescription: testInformation?.description,
        credentialsId: testInformation?.credentials_id,
        artifacts: planningArtifacts,
        messages: [],
    };
}
async function loadAuthoringSession(apiClient, agentSessionId) {
    const agentSession = await apiClient.getAgentSession(agentSessionId);
    const startupParams = agentSession.startup_params;
    if (!startupParams?.url) {
        throw new Error('Agent session does not have a startup URL');
    }
    const artifacts = agentSession.related_artifacts ?? [];
    const testInfo = extractTestInformationFromArtifacts(artifacts);
    const agentStateTestInfo = startupParams.agent_state?.testInformation;
    const artifactViewport = extractViewportFromTestInformation(testInfo);
    const agentStateViewport = extractViewportFromTestInformation(agentStateTestInfo);
    const viewportWidth = artifactViewport.viewportWidth ?? agentStateViewport.viewportWidth;
    const viewportHeight = artifactViewport.viewportHeight ?? agentStateViewport.viewportHeight;
    const editData = await loadExistingTestIfEditing(apiClient, testInfo?.test_id ?? agentStateTestInfo?.test_id, testInfo?.branch_id ?? agentStateTestInfo?.branch_id);
    return {
        sessionId: agentSession.id,
        url: startupParams.url,
        testIntent: testInfo?.test_case ?? '',
        workspaceId: agentSession.workspace_id,
        applicationId: startupParams.application_id,
        testName: testInfo?.name,
        testDescription: testInfo?.description,
        viewportWidth,
        viewportHeight,
        credentialsId: testInfo?.credentials_id ?? agentStateTestInfo?.credentials_id,
        datatables: extractDatatablesFromTestInformation(testInfo) ??
            extractDatatablesFromTestInformation(agentStateTestInfo),
        labels: extractLabelsFromTestInformation(testInfo) ??
            extractLabelsFromTestInformation(agentStateTestInfo),
        branchId: testInfo?.branch_id ?? agentStateTestInfo?.branch_id,
        planId: testInfo?.plan_id ?? agentStateTestInfo?.plan_id,
        devicePreset: testInfo?.device_preset ?? agentStateTestInfo?.device_preset,
        deviceOrientation: testInfo?.device_orientation ?? agentStateTestInfo?.device_orientation,
        scenarioId: testInfo?.scenario_id ?? agentStateTestInfo?.scenario_id,
        ...editData,
        artifacts,
        messages: agentSession.messages ?? [],
    };
}
function getInlineArtifactByName(artifacts, name) {
    if (!artifacts) {
        return undefined;
    }
    return artifacts.find((artifact) => artifact.artifact_type === 'inline' &&
        artifact.name === name);
}
function getJsonFromInlineArtifact(artifact) {
    if (!artifact?.artifact_data) {
        return undefined;
    }
    const data = artifact.artifact_data;
    if (data.type !== 'json') {
        return undefined;
    }
    return data.value;
}
function extractTestInformationFromArtifacts(artifacts) {
    const testInfoArtifact = getInlineArtifactByName(artifacts, 'test_information');
    return getJsonFromInlineArtifact(testInfoArtifact);
}
function extractViewportFromTestInformation(testInformation) {
    if (!testInformation) {
        return {};
    }
    const rawWidth = 'viewport_width' in testInformation
        ? testInformation.viewport_width
        : undefined;
    const rawHeight = 'viewport_height' in testInformation
        ? testInformation.viewport_height
        : undefined;
    const viewportWidth = typeof rawWidth === 'number' ? rawWidth : undefined;
    const viewportHeight = typeof rawHeight === 'number' ? rawHeight : undefined;
    return { viewportWidth, viewportHeight };
}
function extractDatatablesFromTestInformation(testInformation) {
    if (!testInformation) {
        return undefined;
    }
    const datatableId = 'datatable_id' in testInformation
        ? testInformation.datatable_id
        : undefined;
    if (typeof datatableId === 'string' && datatableId) {
        return [datatableId];
    }
    return undefined;
}
function extractLabelsFromTestInformation(testInformation) {
    if (!testInformation) {
        return undefined;
    }
    const labels = 'labels' in testInformation ? testInformation.labels : undefined;
    if (Array.isArray(labels) && labels.every((l) => typeof l === 'string')) {
        return labels;
    }
    return undefined;
}
function extractTestIdFromArtifacts(artifacts) {
    if (!artifacts) {
        return undefined;
    }
    for (const artifact of artifacts) {
        if (artifact.artifact_type === 'remote') {
            const remoteArtifact = artifact;
            if (remoteArtifact.entity_kind === 'Test' && remoteArtifact.entity_id) {
                return remoteArtifact.entity_id;
            }
        }
    }
    return undefined;
}
async function loadExistingTestIfEditing(apiClient, testId, branchId) {
    if (!testId) {
        return {};
    }
    let branchName = constants_1.DefaultBranchName;
    if (branchId) {
        try {
            const branchObj = await apiClient.getBranchById(branchId);
            branchName = branchObj.name ?? branchId;
        }
        catch {
            branchName = branchId;
        }
    }
    try {
        const existingTest = await apiClient.getJourney(testId, branchName);
        const existingFlows = existingTest.flows?.length
            ? await (0, flowResolver_1.getJourneyFlowArray)(existingTest, apiClient, branchName)
            : [];
        return { testId, existingTest, existingFlows };
    }
    catch (error) {
        throw new Error(`Failed to load test for editing (test_id=${testId}, branch=${branchName}): ${error instanceof Error ? error.message : String(error)}`);
    }
}
