"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const EndStep_1 = __importDefault(require("./canonical/EndStep"));
const ElseStep_1 = __importDefault(require("./canonical/ElseStep"));
const mablscript_step_types_1 = require("../mablscript-step-types");
const FlowValidationClass_1 = require("./FlowValidationClass");
class FlowValidationConditionals extends FlowValidationClass_1.FlowValidationClass {
    constructor() {
        super();
        this.flowsTracked = {};
        this.flowsTracked = {};
    }
    trackFlow(flow) {
        if (!this.flowsTracked[flow]) {
            this.flowsTracked[flow] = {
                conditionalStack: [],
                parentlessElseEnd: [],
                elseIfAfterElse: [],
                extraElse: [],
            };
        }
    }
    getTrackedId(flow) {
        if (flow?.reusable && flow?.flow_type === 'mablscript') {
            return `${flow.id}:${flow.description}`;
        }
        return 'root';
    }
    getTrackedState(flow) {
        const trackedId = this.getTrackedId(flow);
        if (!this.flowsTracked[trackedId]) {
            this.trackFlow(trackedId);
        }
        return this.flowsTracked[trackedId];
    }
    processStep(step, humanizedStep, flow) {
        const conditionalStep = step;
        const enabled = !humanizedStep.isDisabledStep;
        const trackedState = this.getTrackedState(flow);
        if (conditionalStep.wrapInConditional &&
            conditionalStep.wrapInConditionalType === mablscript_step_types_1.CONDITIONAL_TYPE_IF) {
            humanizedStep.insideConditionalDepth =
                trackedState.conditionalStack.length;
            if (enabled) {
                trackedState.conditionalStack.push(humanizedStep);
            }
        }
        else if (step.stepType === EndStep_1.default.getStepType()) {
            if (enabled) {
                if (trackedState.conditionalStack.length === 0) {
                    trackedState.parentlessElseEnd.push(humanizedStep);
                }
                trackedState.conditionalStack.pop();
            }
            humanizedStep.insideConditionalDepth =
                trackedState.conditionalStack.length;
        }
        else if (step.stepType === ElseStep_1.default.getStepType()) {
            if (enabled) {
                if (trackedState.conditionalStack.length === 0) {
                    trackedState.parentlessElseEnd.push(humanizedStep);
                }
                else {
                    const parentIf = trackedState.conditionalStack[trackedState.conditionalStack.length - 1];
                    if (parentIf.elseStepExists === true) {
                        trackedState.extraElse.push(humanizedStep);
                    }
                    else {
                        parentIf.elseStepExists = true;
                    }
                }
            }
            humanizedStep.insideConditionalDepth = Math.max(trackedState.conditionalStack.length - 1, 0);
        }
        else if (conditionalStep.wrapInConditional &&
            conditionalStep.wrapInConditionalType === mablscript_step_types_1.CONDITIONAL_TYPE_ELSEIF) {
            if (enabled) {
                if (trackedState.conditionalStack.length === 0) {
                    trackedState.parentlessElseEnd.push(humanizedStep);
                }
                else {
                    const parentIf = trackedState.conditionalStack[trackedState.conditionalStack.length - 1];
                    if (parentIf.elseStepExists) {
                        trackedState.elseIfAfterElse.push(humanizedStep);
                    }
                }
            }
            humanizedStep.insideConditionalDepth = Math.max(trackedState.conditionalStack.length - 1, 0);
        }
        else {
            humanizedStep.insideConditionalDepth =
                trackedState.conditionalStack.length;
        }
        return humanizedStep;
    }
    finalizeValidations(humanizedSteps) {
        Object.entries(this.flowsTracked).forEach(([flow, trackedValidation]) => {
            trackedValidation.conditionalStack.forEach((unclosedIfStep) => {
                unclosedIfStep?.validation?.push({
                    name: 'unclosedIfConditional',
                    humanized: `Conditional statement ${flow !== 'root' ? 'in flow ' : ''}has no END step.`,
                });
            });
            trackedValidation.parentlessElseEnd.forEach((parentlessConditional) => {
                parentlessConditional?.validation?.push({
                    name: 'parentlessConditional',
                    humanized: `Step ${flow !== 'root' ? 'in flow ' : ''}has no parent IF condition.`,
                });
            });
            trackedValidation.extraElse.forEach((extraElseStatement) => {
                extraElseStatement?.validation?.push({
                    name: 'isExtraElse',
                    humanized: `Second ELSE in ${flow !== 'root' ? 'flow ' : ''}conditional statement`,
                });
            });
            trackedValidation.elseIfAfterElse.forEach((elseIfAfterElse) => {
                elseIfAfterElse?.validation?.push({
                    name: 'isElseIfAfterElse',
                    humanized: `ELSE IF after ELSE in ${flow !== 'root' ? 'flow ' : ''}conditional statement`,
                });
            });
        });
        return humanizedSteps;
    }
}
exports.default = FlowValidationConditionals;
