"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JavaScriptAction = void 0;
exports.isJavaScriptActionDescriptor = isJavaScriptActionDescriptor;
const mablscriptFind_1 = require("../mablscriptFind");
const MablAction_1 = require("../MablAction");
const SnippetsDescriptor_1 = require("../types/SnippetsDescriptor");
const MABLSCRIPT_NAME = 'evaluate_js';
function isLegacySnippetReference(value) {
    return typeof value === 'object' && !!value.id && !('invariant_id' in value);
}
function isReusableSnippetReference(value) {
    return typeof value === 'object' && !!value.id && !!value.invariant_id;
}
function isInlineSnippetReference(value) {
    return (typeof value === 'object' &&
        typeof value.body === 'string' &&
        Array.isArray(value.parameters) &&
        !('id' in value) &&
        !('invariant_id' in value));
}
function isSnippetOptions(value) {
    return value && 'parameter_overrides' in value;
}
class JavaScriptAction extends MablAction_1.MablAction {
    static mablscriptName = MABLSCRIPT_NAME;
    static mablScriptStepNames = [MABLSCRIPT_NAME];
    javaScript;
    constructor(name, args) {
        super(name, MABLSCRIPT_NAME, args);
        if (args.length < 1 || args.length > 2) {
            throw new Error('EvaluateJS action expects 1 or 2 arguments');
        }
        const scriptOrSnippetReference = args[0];
        if (!scriptOrSnippetReference ||
            !(typeof scriptOrSnippetReference === 'string' ||
                typeof scriptOrSnippetReference === 'object')) {
            throw new Error('EvaluateJS action expects the first argument to be a string or object');
        }
        if (typeof scriptOrSnippetReference === 'string') {
            this.javaScript = {
                encodedJS: scriptOrSnippetReference,
                actionCode: MABLSCRIPT_NAME,
            };
        }
        else if (isLegacySnippetReference(scriptOrSnippetReference)) {
            const { id } = scriptOrSnippetReference;
            this.javaScript = {
                snippetInvariantId: id,
                actionCode: MABLSCRIPT_NAME,
            };
        }
        else if (isReusableSnippetReference(scriptOrSnippetReference)) {
            const { id, invariant_id } = scriptOrSnippetReference;
            this.javaScript = {
                snippetId: id,
                snippetInvariantId: invariant_id,
                parameterOverrides: [],
                actionCode: MABLSCRIPT_NAME,
            };
            const snippetOptions = args[1];
            if (isSnippetOptions(snippetOptions)) {
                this.javaScript.parameterOverrides = snippetOptions.parameter_overrides;
            }
        }
        else if (isInlineSnippetReference(scriptOrSnippetReference)) {
            this.javaScript = {
                inlineSnippet: scriptOrSnippetReference,
                parameterOverrides: [],
                actionCode: MABLSCRIPT_NAME,
            };
            const snippetOptions = args[1];
            if (isSnippetOptions(snippetOptions)) {
                this.javaScript.parameterOverrides = snippetOptions.parameter_overrides;
            }
        }
        else {
            throw new Error(`Invalid argument for EvaluateJS action: ${JSON.stringify(scriptOrSnippetReference)}`);
        }
    }
    toDescriptor() {
        return { javaScript: this.javaScript, actionCode: this.actionCode };
    }
    static fromDescriptor(descriptor) {
        const { javaScript } = descriptor;
        if ((0, SnippetsDescriptor_1.isReusableSnippetDescriptor)(javaScript)) {
            return new JavaScriptAction(JavaScriptAction.mablscriptName, [
                {
                    id: javaScript.snippetId,
                    invariant_id: javaScript.snippetInvariantId,
                },
                { parameter_overrides: javaScript.parameterOverrides },
            ]);
        }
        else if ((0, SnippetsDescriptor_1.isInlineSnippetDescriptor)(javaScript)) {
            return new JavaScriptAction(JavaScriptAction.mablscriptName, [
                javaScript.inlineSnippet,
                { parameter_overrides: javaScript.parameterOverrides },
            ]);
        }
        else if ((0, SnippetsDescriptor_1.isLegacyReusableSnippetDescriptor)(javaScript)) {
            return new JavaScriptAction(JavaScriptAction.mablscriptName, [
                {
                    id: javaScript.snippetInvariantId,
                },
            ]);
        }
        else if ((0, SnippetsDescriptor_1.isLegacyInlineJavaScriptDescriptor)(javaScript)) {
            return new JavaScriptAction(JavaScriptAction.mablscriptName, [
                javaScript.encodedJS,
            ]);
        }
        throw new Error(`Invalid javascript action descriptor: ${JSON.stringify(descriptor)}`);
    }
    static fromYaml(formatted) {
        const jsDescriptor = formatted.javaScript ?? formatted;
        let snippetOptions;
        if (jsDescriptor.parameterOverrides) {
            snippetOptions = {
                parameter_overrides: jsDescriptor.parameterOverrides,
            };
        }
        const args = [];
        if (jsDescriptor.code) {
            args.push(jsDescriptor.code);
        }
        else if (jsDescriptor.encodedJS) {
            args.push(jsDescriptor.encodedJS);
        }
        else if (jsDescriptor.body) {
            args.push(jsDescriptor.body);
        }
        else if (jsDescriptor.inlineSnippet) {
            args.push(jsDescriptor.inlineSnippet);
        }
        else if (jsDescriptor.snippet) {
            args.push(jsDescriptor.snippet);
        }
        else if (jsDescriptor.snippetInvariantId && jsDescriptor.snippetId) {
            args.push({
                id: jsDescriptor.snippetId,
                invariant_id: jsDescriptor.snippetInvariantId,
            });
        }
        else if (jsDescriptor.snippetInvariantId) {
            args.push({
                id: jsDescriptor.snippetInvariantId,
            });
        }
        else if (jsDescriptor.snippetId) {
            args.push({
                id: jsDescriptor.snippetId,
            });
        }
        else {
            throw new Error(`Cannot import action from yaml: ${JSON.stringify(formatted)}`);
        }
        if (snippetOptions) {
            args.push(snippetOptions);
        }
        return new JavaScriptAction(MABLSCRIPT_NAME, args);
    }
    toMablscript() {
        if ((0, SnippetsDescriptor_1.isReusableSnippetDescriptor)(this.javaScript)) {
            const snippetReference = (0, mablscriptFind_1.buildStepArgumentString)({
                params: {
                    id: this.javaScript.snippetId,
                    invariant_id: this.javaScript.snippetInvariantId,
                    snippet_type: 'javascript',
                },
                legacy: true,
            });
            const snippetOptions = `, {parameter_overrides: ${(0, mablscriptFind_1.buildStepArgumentString)({ params: this.javaScript.parameterOverrides, legacy: true })}}`;
            return `evaluate_js(${snippetReference}${snippetOptions})`;
        }
        if ((0, SnippetsDescriptor_1.isInlineSnippetDescriptor)(this.javaScript)) {
            const snippetReference = (0, mablscriptFind_1.buildStepArgumentString)({
                params: { ...this.javaScript.inlineSnippet, snippet_type: 'javascript' },
                legacy: true,
            });
            const snippetOptions = `, {parameter_overrides: ${(0, mablscriptFind_1.buildStepArgumentString)({
                params: this.javaScript.parameterOverrides,
                legacy: true,
            })}}`;
            return `evaluate_js(${snippetReference}${snippetOptions})`;
        }
        if ((0, SnippetsDescriptor_1.isLegacyReusableSnippetDescriptor)(this.javaScript)) {
            return `evaluate_js({id: "${this.javaScript.snippetInvariantId}", snippet_type: "javascript"})`;
        }
        if ((0, SnippetsDescriptor_1.isLegacyInlineJavaScriptDescriptor)(this.javaScript)) {
            return `evaluate_js("${this.javaScript.encodedJS}")`;
        }
        throw new Error(`Cannot export action to mablscript: ${JSON.stringify(this.javaScript)}`);
    }
    getInputVariables() {
        if ((0, SnippetsDescriptor_1.isInlineSnippetDescriptor)(this.javaScript) ||
            (0, SnippetsDescriptor_1.isReusableSnippetDescriptor)(this.javaScript)) {
            return MablAction_1.MablAction.findUniqueVariableReferencesInValue(this.javaScript.parameterOverrides.map((override) => override.value));
        }
        return [];
    }
}
exports.JavaScriptAction = JavaScriptAction;
function isJavaScriptActionDescriptor(value) {
    return value.javaScript !== undefined;
}
