"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveStepReference = resolveStepReference;
const expandSteps_1 = require("./expandSteps");
const stepIndexUtils_1 = require("../trainer/sharedUtils/stepIndexUtils");
function resolveStepReference(snapshot, reference) {
    const expanded = (0, expandSteps_1.expandSessionSteps)(snapshot);
    if (expanded.length === 0) {
        return {
            success: false,
            errorMessage: 'No steps in session snapshot',
        };
    }
    const byCanonicalId = matchByCanonicalId(expanded, reference);
    if (byCanonicalId !== undefined) {
        return {
            success: true,
            stepId: (0, expandSteps_1.addressableStepId)(expanded[byCanonicalId], byCanonicalId),
            flatIndex: byCanonicalId,
        };
    }
    const bySynthetic = matchBySyntheticId(expanded, reference);
    if (bySynthetic !== undefined) {
        return {
            success: true,
            stepId: (0, expandSteps_1.addressableStepId)(expanded[bySynthetic], bySynthetic),
            flatIndex: bySynthetic,
        };
    }
    const byPosition = matchByDotNotationOrFlatPosition(expanded, reference);
    if (byPosition !== undefined) {
        return {
            success: true,
            stepId: (0, expandSteps_1.addressableStepId)(expanded[byPosition], byPosition),
            flatIndex: byPosition,
        };
    }
    return {
        success: false,
        errorMessage: `Step not found: "${reference}". Pass the step id from list-steps' \`id\` field, a 1-based position like "14" or "3.2", or the canonical step id.`,
    };
}
function matchByCanonicalId(expanded, reference) {
    for (let i = 0; i < expanded.length; i++) {
        if (expanded[i].step.stepId() === reference) {
            return i;
        }
    }
    return undefined;
}
function matchBySyntheticId(expanded, reference) {
    for (let i = 0; i < expanded.length; i++) {
        if ((0, expandSteps_1.addressableStepId)(expanded[i], i) === reference) {
            return i;
        }
    }
    return undefined;
}
function matchByDotNotationOrFlatPosition(expanded, reference) {
    if (!stepIndexUtils_1.DOT_NOTATION_PATTERN.test(reference)) {
        return undefined;
    }
    const segments = reference.split('.').map((s) => Number.parseInt(s, 10));
    if (segments.some((n) => !Number.isFinite(n) || n < 1)) {
        return undefined;
    }
    let windowStart = 0;
    let windowEnd = expanded.length - 1;
    let currentIndex;
    for (const oneBasedSeg of segments) {
        const siblings = [];
        let i = windowStart;
        while (i <= windowEnd) {
            siblings.push(i);
            i = expanded[i].subtreeEndIndex + 1;
        }
        if (oneBasedSeg > siblings.length) {
            return undefined;
        }
        currentIndex = siblings[oneBasedSeg - 1];
        windowStart = currentIndex + 1;
        windowEnd = expanded[currentIndex].subtreeEndIndex;
    }
    return currentIndex;
}
