"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createOneTimeEvaluateJsStep = createOneTimeEvaluateJsStep;
exports.createEvaluateJsStep = createEvaluateJsStep;
exports.createEvaluateJsStepWithUpdatedReusableSnippet = createEvaluateJsStepWithUpdatedReusableSnippet;
exports.isJavascriptAction = isJavascriptAction;
exports.humanizeEvaluateJSStep = humanizeEvaluateJSStep;
exports.evaluateJSStepToAIString = evaluateJSStepToAIString;
const BaseStep_1 = __importDefault(require("./BaseStep"));
const mablscript_step_types_1 = require("../../mablscript-step-types");
const JavaScriptAction_1 = require("@mablhq/test-model/actions/JavaScriptAction");
const SnippetsDescriptor_1 = require("@mablhq/test-model/types/SnippetsDescriptor");
const mablApi_1 = require("../../../../mablApi");
const snippetUtils_1 = require("../snippetUtils");
const mablscriptFind_1 = require("@mablhq/test-model/mablscriptFind");
const assert_utils_1 = require("./assert-utils");
const yaml_utils_1 = require("../yaml-utils");
const MablStepV2_1 = require("@mablhq/test-model/MablStepV2");
class EvaluateJSStep extends BaseStep_1.default {
    static getStepType() {
        return mablscript_step_types_1.StepType.EVALUATE_JS;
    }
    static isEditable(snippet) {
        return !!snippet;
    }
    constructor(javaScript, wrapInConditional = false, wrapInConditionalType, snippet) {
        super(EvaluateJSStep.getStepType());
        this.javaScript = javaScript;
        this.snippet = snippet;
        this.options = {
            editable: EvaluateJSStep.isEditable(snippet),
        };
        this.wrapInConditional = wrapInConditional;
        this.wrapInConditionalType = wrapInConditionalType;
    }
    getSnippetInvariantId() {
        return getSnippetInvariantId(this);
    }
    setAsConditional() {
        this.wrapInConditional = true;
    }
    setAsConditionalType(wrapInConditionalType) {
        this.wrapInConditionalType = wrapInConditionalType;
    }
    generateMablscript() {
        const evaluateJsAction = JavaScriptAction_1.JavaScriptAction.fromDescriptor({
            javaScript: this.javaScript,
        });
        let mablscript = evaluateJsAction.toMablscript();
        if (this.wrapInConditional) {
            mablscript =
                this.wrapInConditionalType === mablscript_step_types_1.ConditionalType.ELSEIF
                    ? `conditional_else().${mablscript}.conditional_else_if()`
                    : `${mablscript}.conditional_if()`;
        }
        return mablscript;
    }
    inputVariables() {
        if ((0, SnippetsDescriptor_1.isInlineSnippetDescriptor)(this.javaScript) ||
            (0, SnippetsDescriptor_1.isReusableSnippetDescriptor)(this.javaScript) ||
            (0, snippetUtils_1.getResolvedSnippetParameters)(this) !== undefined) {
            return (0, snippetUtils_1.getVariableReferencesFromSnippetParameters)(this);
        }
        return undefined;
    }
    static generateStepFromMablStep(mablEvaluateJavaScriptStep, importer) {
        let wrapInConditional = false;
        let wrapInConditionalType;
        let javaScript;
        if ((0, assert_utils_1.isIfConditionStep)(mablEvaluateJavaScriptStep)) {
            wrapInConditional = true;
            javaScript = mablEvaluateJavaScriptStep.primaryAction.javaScript;
            wrapInConditionalType = mablscript_step_types_1.ConditionalType.IF;
        }
        else if ((0, assert_utils_1.isElseIfConditionStep)(mablEvaluateJavaScriptStep)) {
            wrapInConditional = true;
            javaScript = mablEvaluateJavaScriptStep.primaryAction.javaScript;
            wrapInConditionalType = mablscript_step_types_1.ConditionalType.ELSEIF;
        }
        else {
            javaScript = mablEvaluateJavaScriptStep.evaluateJsAction.javaScript;
        }
        javaScript = (0, snippetUtils_1.canonicalizeJavaScriptDescriptor)(javaScript, importer.variables);
        let snippet;
        if ((0, SnippetsDescriptor_1.isReusableSnippetDescriptor)(javaScript) ||
            (0, SnippetsDescriptor_1.isLegacyReusableSnippetDescriptor)(javaScript)) {
            snippet = importer.snippets[javaScript.snippetInvariantId];
        }
        else if ((0, SnippetsDescriptor_1.isInlineSnippetDescriptor)(javaScript)) {
            if (javaScript.inlineSnippet.body) {
                snippet = javaScript.inlineSnippet;
            }
        }
        else if ((0, SnippetsDescriptor_1.isLegacyInlineJavaScriptDescriptor)(javaScript)) {
            return createOneTimeEvaluateJsStep(javaScript.encodedJS, wrapInConditional, wrapInConditionalType);
        }
        return new EvaluateJSStep(javaScript, wrapInConditional, wrapInConditionalType, snippet);
    }
    static create(descriptor) {
        const step = new EvaluateJSStep(descriptor.javaScript, descriptor.wrapInConditional, descriptor.wrapInConditionalType, descriptor.snippet);
        step.setStepId(descriptor.id ?? MablStepV2_1.MablStepV2.generateStepId());
        return step;
    }
}
exports.default = EvaluateJSStep;
function createOneTimeEvaluateJsStep(encodedJS, wrapInConditional = false, wrapInConditionalType) {
    return createEvaluateJsStep({ encodedJS }, wrapInConditional, wrapInConditionalType, {
        body: encodedJS,
        snippet_type: mablApi_1.SnippetTypeEnum.Javascript,
    });
}
function createEvaluateJsStep(javaScript, wrapInConditional = false, wrapInConditionalType, snippet, id) {
    return EvaluateJSStep.create({
        javaScript,
        wrapInConditional,
        wrapInConditionalType,
        snippet,
        id,
    });
}
function createEvaluateJsStepWithUpdatedReusableSnippet(step, snippet) {
    if (!(0, snippetUtils_1.isSnippetReusableAndRelevant)(step.javaScript, snippet)) {
        return step;
    }
    return EvaluateJSStep.create({
        javaScript: (0, snippetUtils_1.updateJavaScriptDescriptorIfReusable)(step.javaScript, snippet),
        wrapInConditional: step.wrapInConditional,
        wrapInConditionalType: step.wrapInConditionalType,
        snippet,
        id: step.id,
    });
}
function isJavascriptAction(action) {
    return action?.name === JavaScriptAction_1.JavaScriptAction.mablscriptName;
}
function humanizeEvaluateJSStep(step) {
    let humanized = (0, mablscriptFind_1.humanizeSnippet)(getSnippetInvariantId(step), step.snippet);
    if (step.wrapInConditional) {
        humanized = `${step.wrapInConditionalType === mablscript_step_types_1.ConditionalType.ELSEIF ? 'ELSE IF' : 'IF'} ${humanized} evaluates true`;
    }
    else {
        humanized = `Evaluate ${humanized}`;
    }
    return humanized;
}
function getSnippetInvariantId(step) {
    if ((0, SnippetsDescriptor_1.isReusableSnippetDescriptor)(step.javaScript) ||
        (0, SnippetsDescriptor_1.isLegacyReusableSnippetDescriptor)(step.javaScript)) {
        return step.javaScript.snippetInvariantId;
    }
    return;
}
function evaluateJSStepToAIString(step) {
    const snippetName = step.snippet?.name;
    const isReusable = (0, SnippetsDescriptor_1.isReusableSnippetDescriptor)(step.javaScript) ||
        (0, SnippetsDescriptor_1.isLegacyReusableSnippetDescriptor)(step.javaScript);
    if (step.wrapInConditional) {
        return (0, yaml_utils_1.toYaml)({
            stepType: step.wrapInConditionalType === mablscript_step_types_1.ConditionalType.ELSEIF
                ? 'else_if'
                : 'if',
            condition: {
                type: 'javascript',
                snippet_name: snippetName,
                snippet_type: isReusable ? 'reusable' : 'one_time',
            },
        });
    }
    return (0, yaml_utils_1.toYaml)({
        stepType: step.stepType,
        snippet_name: snippetName,
        snippet_type: isReusable ? 'reusable' : 'one_time',
    });
}
