"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateTestFlows = validateTestFlows;
const errors_1 = require("../errors");
const structural_1 = require("./structural");
const cross_step_1 = require("./cross-step");
const semantic_1 = require("./semantic");
function remapPaths(result, flowIndex, flowId) {
    const prefix = flowId
        ? ['flows', flowId]
        : ['flows', flowIndex];
    for (const err of result.errors) {
        err.path = [...prefix, ...err.path];
    }
    for (const warn of result.warnings) {
        warn.path = [...prefix, ...warn.path];
    }
    return result;
}
function validateTestFlows(flows, options) {
    const results = [];
    for (let i = 0; i < flows.length; i++) {
        const flow = flows[i];
        const jsonSteps = flow.jsonSteps;
        const structuralResult = (0, structural_1.validateStructure)(jsonSteps, options);
        if (!structuralResult.valid) {
            results.push(remapPaths(structuralResult, i, flow.id));
            continue;
        }
        results.push(remapPaths(structuralResult, i, flow.id));
        if (options.semanticValidation !== false) {
            const semanticResult = (0, semantic_1.validateSemantics)(jsonSteps.steps, options);
            results.push(remapPaths(semanticResult, i, flow.id));
        }
    }
    const structuralMerged = (0, errors_1.mergeResults)(...results);
    if (!structuralMerged.valid) {
        return structuralMerged;
    }
    if (options.crossStepValidation !== false) {
        const inlineSteps = [];
        const inlineFlowBoundaries = [];
        for (let i = 0; i < flows.length; i++) {
            const flow = flows[i];
            if (!flow.reusable) {
                const steps = flow.jsonSteps.steps;
                inlineFlowBoundaries.push({
                    flowIndex: i,
                    flowId: flow.id,
                    startStep: inlineSteps.length,
                    stepCount: steps.length,
                });
                inlineSteps.push(...steps);
            }
        }
        if (inlineSteps.length > 0) {
            const inlineConditionalResult = (0, cross_step_1.validateConditionalBlocks)(inlineSteps, options);
            const inlineVariableResult = (0, cross_step_1.validateVariableOrder)(inlineSteps);
            for (const result of [inlineConditionalResult, inlineVariableResult]) {
                for (const item of [...result.errors, ...result.warnings]) {
                    const globalStepIndex = typeof item.path[1] === 'number' ? item.path[1] : -1;
                    if (item.path[0] === 'steps' && globalStepIndex >= 0) {
                        const boundary = inlineFlowBoundaries.find((b) => globalStepIndex >= b.startStep &&
                            globalStepIndex < b.startStep + b.stepCount);
                        if (boundary) {
                            const localIndex = globalStepIndex - boundary.startStep;
                            const prefix = boundary.flowId
                                ? ['flows', boundary.flowId]
                                : ['flows', boundary.flowIndex];
                            item.path = [
                                ...prefix,
                                'steps',
                                localIndex,
                                ...item.path.slice(2),
                            ];
                        }
                    }
                }
                results.push(result);
            }
        }
        const reusableOptions = { ...options, strict: true };
        for (let i = 0; i < flows.length; i++) {
            const flow = flows[i];
            if (flow.reusable) {
                const steps = flow.jsonSteps.steps;
                const conditionalResult = (0, cross_step_1.validateConditionalBlocks)(steps, reusableOptions);
                const variableResult = (0, cross_step_1.validateVariableOrder)(steps);
                results.push(remapPaths(conditionalResult, i, flow.id));
                results.push(remapPaths(variableResult, i, flow.id));
            }
        }
    }
    return (0, errors_1.mergeResults)(...results);
}
