"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.addressableStepId = addressableStepId;
exports.expandSteps = expandSteps;
exports.expandSessionSteps = expandSessionSteps;
const importer_1 = require("@mablhq/test-model/importer");
const EvaluateFlowStep_1 = require("@mablhq/test-model/steps/EvaluateFlowStep");
const StepGroupStep_1 = require("@mablhq/test-model/steps/StepGroupStep");
function addressableStepId(entry, flatIndex) {
    return entry.step.stepId() ?? `${entry.flow.id}:${flatIndex}`;
}
function expandSteps(topLevelFlows, flowsByInvariantId) {
    const out = [];
    const visited = new Set();
    for (const flow of topLevelFlows) {
        walk((0, importer_1.parseMablScriptIntoSteps)(flow), flow, undefined);
    }
    return out;
    function walk(steps, containingFlow, parentStepId) {
        for (const step of steps) {
            const ownIndex = out.length;
            out.push({
                flow: containingFlow,
                step,
                parentStepId,
                subtreeEndIndex: ownIndex,
            });
            if ((0, StepGroupStep_1.isStepGroupStep)(step)) {
                walk(step.getSteps(), containingFlow, step.stepId());
                out[ownIndex].subtreeEndIndex = out.length - 1;
                continue;
            }
            if ((0, EvaluateFlowStep_1.isEvaluateFlowStep)(step)) {
                const invariantId = step.flowDescriptor.invariant_id;
                if (!invariantId || visited.has(invariantId)) {
                    continue;
                }
                const nestedFlow = flowsByInvariantId.get(invariantId);
                if (!nestedFlow) {
                    continue;
                }
                visited.add(invariantId);
                walk((0, importer_1.parseMablScriptIntoSteps)(nestedFlow), nestedFlow, step.stepId());
                visited.delete(invariantId);
                out[ownIndex].subtreeEndIndex = out.length - 1;
            }
        }
    }
}
function indexFlowsByInvariantId(flows) {
    const byInvariant = new Map();
    for (const flow of flows) {
        if (flow.invariant_id) {
            byInvariant.set(flow.invariant_id, flow);
        }
    }
    return byInvariant;
}
function expandSessionSteps(snapshot) {
    const topLevelFlowIds = new Set(snapshot.test.flows ?? []);
    const topLevelFlows = snapshot.flows.filter((flow) => flow.id !== undefined && topLevelFlowIds.has(flow.id));
    return expandSteps(topLevelFlows, indexFlowsByInvariantId(snapshot.flows));
}
