"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MablStep = exports.StepDescriptionSource = void 0;
exports.buildSourceRepresentationOfObject = buildSourceRepresentationOfObject;
exports.buildObjectString = buildObjectString;
exports.isMablStepV1 = isMablStepV1;
const mablscriptFind_1 = require("./mablscriptFind");
const MablAction_1 = require("./MablAction");
const MablSymbol_1 = require("./MablSymbol");
const fast_json_stable_stringify_1 = __importDefault(require("fast-json-stable-stringify"));
var StepDescriptionSource;
(function (StepDescriptionSource) {
    StepDescriptionSource["AI"] = "ai";
    StepDescriptionSource["Default"] = "default";
    StepDescriptionSource["User"] = "user";
})(StepDescriptionSource || (exports.StepDescriptionSource = StepDescriptionSource = {}));
class MablStep extends MablAction_1.MablAction {
    id;
    actions;
    disabled;
    description;
    annotation;
    stepSourceIndexInFlow;
    static mablScriptStepNames = ['mablStep'];
    static yamlMablScriptNames = ['MablStep'];
    stepVersion = 1;
    constructor(name, args, actions, actionCode) {
        super(name, actionCode, args);
        this.actions = actions;
    }
    getStepVersion() {
        return this.stepVersion;
    }
    setStepId(id) {
        this.id = id;
    }
    stepId() {
        return this.id;
    }
    canContinueOnFailure() {
        return false;
    }
    canFailAtEnd() {
        return false;
    }
    getStepName() {
        return 'UnimplementedStep';
    }
    isDisabled() {
        return !!this.disabled;
    }
    setDisabled(disabled) {
        this.disabled = disabled;
    }
    setAnnotation(annotation) {
        this.annotation = annotation;
    }
    getAnnotation() {
        return this.annotation;
    }
    setDescription(description) {
        this.description = description;
    }
    getDescription() {
        return this.description;
    }
    setStepSourceIndexInFlow(index) {
        this.stepSourceIndexInFlow = index;
    }
    getStepSourceIndexInFlow() {
        return this.stepSourceIndexInFlow;
    }
    getResolvedDescription() {
        return (this.annotation?.description || this.description || this.getStepName());
    }
    substituteMablscriptVariable(argument) {
        if ((0, MablSymbol_1.isMablSymbolObject)(argument)) {
            return argument.name;
        }
        if ((0, MablAction_1.argumentIsMablVariable)(argument)) {
            const matches = argument.match(MablSymbol_1.SINGLE_VARIABLE_PATTERN_REGEX);
            if (matches) {
                return matches[1];
            }
        }
        return `"${argument}"`;
    }
    toStepDescriptor() {
        const formatted = {
            names: this.actions.map((action) => action.getActionName()),
        };
        formatted.names.push(this.getActionName());
        return formatted;
    }
    annotationsOnStep() {
        return !!this.annotation?.note || !!this.annotation?.description;
    }
    annotationsAsYml() {
        const result = {};
        if (this.annotationsOnStep()) {
            result.annotation = this.annotation;
        }
        if (this.description) {
            result.description = this.description;
        }
        if (this.isDisabled()) {
            result.disabled = this.isDisabled();
        }
        return result;
    }
    getFormattedStep() {
        const formatted = {};
        formatted[this.getStepName()] =
            this.annotationsAsYml();
        const { actionCode, ...stepDescriptor } = this.toStepDescriptor();
        Object.assign(formatted[this.getStepName()], stepDescriptor);
        if (this.stepId()) {
            formatted[this.getStepName()].id = this.stepId();
        }
        return formatted;
    }
    toMablscript() {
        return '';
    }
    toLineDiffFormat(_omitStepId = false) {
        const lineDiffProperties = {
            annotation: this.annotation && Object.keys(this.annotation).length > 0
                ? this.annotation
                : undefined,
            disabled: this.isDisabled(),
            mablscript: this.toMablscript(),
        };
        return this.stringify(lineDiffProperties);
    }
    stringify(value) {
        return (0, fast_json_stable_stringify_1.default)(value);
    }
    static cloneAndRemoveUndefinedEntriesFromObject(obj) {
        const clone = {};
        Object.entries(obj).forEach(([key, value]) => {
            if (value !== undefined) {
                if (!value || typeof value !== 'object' || Array.isArray(value)) {
                    clone[key] = value;
                }
                else {
                    clone[key] = MablStep.cloneAndRemoveUndefinedEntriesFromObject(value);
                }
            }
        });
        return clone;
    }
}
exports.MablStep = MablStep;
function buildSourceRepresentationOfObject(object) {
    const stringedValues = Object.entries(object).map(([key, value]) => {
        if (Array.isArray(value)) {
            return `${key}: [${value
                .map((arrayVal) => buildSourceRepresentationOfObject(arrayVal))
                .join(', ')}]`;
        }
        else if (typeof value !== 'object') {
            if (typeof value === 'number') {
                return `${key}: ${value}`;
            }
            return `${key}: "${(0, mablscriptFind_1.escapeMablscriptString)(value)}"`;
        }
        return `${key}: ${buildSourceRepresentationOfObject(value)}`;
    });
    return `{${stringedValues.join(', ')}}`;
}
function buildObjectString(objectString) {
    const final = [];
    Object.keys(objectString)
        .filter((key) => key !== 'value')
        .forEach((key) => {
        if (typeof objectString[key] === 'undefined') {
            return final;
        }
        if (typeof objectString[key] === 'string') {
            return final.push(`${key}: "${(0, mablscriptFind_1.escapeMablscriptString)(objectString[key])}"`);
        }
        else if (typeof objectString[key] === 'number') {
            return final.push(`${key}: ${objectString[key]}`);
        }
        else if (Array.isArray(objectString[key])) {
            return final.push(`"${key}": [${objectString[key]
                .map((arrayVal) => `"${(0, mablscriptFind_1.escapeMablscriptString)(arrayVal)}"`)
                .join(', ')}]`);
        }
        return final.push(`${key}: {${buildObjectString(objectString[key])}}`);
    });
    return final;
}
function isMablStepV1(value) {
    if (value === undefined || value === null) {
        return false;
    }
    const mablStep = value;
    return !!mablStep.getStepVersion && mablStep.getStepVersion() === 1;
}
