var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import VMUtil from "../../../../Utils/VM/VMAPI";
import ComponentCode from "../../ComponentCode";
import BadDataException from "../../../../../Types/Exception/BadDataException";
import ComponentID from "../../../../../Types/Workflow/ComponentID";
import Components, { ConditionOperator, ConditionValueType, } from "../../../../../Types/Workflow/Components/Condition";
import CaptureSpan from "../../../../Utils/Telemetry/CaptureSpan";
export default class IfElse extends ComponentCode {
    constructor() {
        super();
        const Component = Components.find((i) => {
            return i.id === ComponentID.IfElse;
        });
        if (!Component) {
            throw new BadDataException("Custom JavaScript Component not found.");
        }
        this.setMetadata(Component);
    }
    async run(args, options) {
        var _a, _b;
        const yesPort = this.getMetadata().outPorts.find((p) => {
            return p.id === "yes";
        });
        if (!yesPort) {
            throw options.onError(new BadDataException("Yes port not found"));
        }
        const noPort = this.getMetadata().outPorts.find((p) => {
            return p.id === "no";
        });
        if (!noPort) {
            throw options.onError(new BadDataException("No port not found"));
        }
        try {
            /*
             * Set timeout
             * Inject args
             * Inject dependencies
             */
            // Get explicit types from dropdowns, default to text
            let input1Type = args["input-1-type"] || ConditionValueType.Text;
            let input2Type = args["input-2-type"] || ConditionValueType.Text;
            /*
             * When types differ, coerce both to the more specific type
             * so comparisons like text "true" == boolean true work correctly.
             * Priority: Null/Undefined keep as-is, Boolean > Number > Text.
             */
            if (input1Type !== input2Type) {
                const isNullish = (t) => {
                    return (t === ConditionValueType.Null || t === ConditionValueType.Undefined);
                };
                if (!isNullish(input1Type) && !isNullish(input2Type)) {
                    const typePriority = {
                        [ConditionValueType.Boolean]: 2,
                        [ConditionValueType.Number]: 1,
                        [ConditionValueType.Text]: 0,
                    };
                    const p1 = (_a = typePriority[input1Type]) !== null && _a !== void 0 ? _a : 0;
                    const p2 = (_b = typePriority[input2Type]) !== null && _b !== void 0 ? _b : 0;
                    const commonType = p1 >= p2 ? input1Type : input2Type;
                    input1Type = commonType;
                    input2Type = commonType;
                }
            }
            const formatValue = (value, valueType) => {
                const strValue = typeof value === "object"
                    ? JSON.stringify(value)
                    : String(value !== null && value !== void 0 ? value : "");
                switch (valueType) {
                    case ConditionValueType.Boolean:
                        return strValue === "true" ? "true" : "false";
                    case ConditionValueType.Number:
                        return isNaN(Number(strValue)) ? "0" : String(Number(strValue));
                    case ConditionValueType.Null:
                        return "null";
                    case ConditionValueType.Undefined:
                        return "undefined";
                    case ConditionValueType.Text:
                    default:
                        return `"${strValue}"`;
                }
            };
            args["input-1"] = formatValue(args["input-1"], input1Type);
            args["input-2"] = formatValue(args["input-2"], input2Type);
            const serialize = (arg) => {
                if (typeof arg === "string") {
                    return arg.replace(/\n/g, "--newline--");
                }
                return arg;
            };
            let code = `
                    const input1 = ${serialize(args["input-1"]) || ""};

                    const input2 = ${serialize(args["input-2"]) || ""};
                    
                    `;
            if (args["operator"] === ConditionOperator.Contains) {
                code += `return String(input1).includes(String(input2));`;
            }
            else if (args["operator"] === ConditionOperator.DoesNotContain) {
                code += `return !String(input1).includes(String(input2));`;
            }
            else if (args["operator"] === ConditionOperator.StartsWith) {
                code += `return String(input1).startsWith(String(input2));`;
            }
            else if (args["operator"] === ConditionOperator.EndsWith) {
                code += `return String(input1).endsWith(String(input2));`;
            }
            else {
                code += `return input1 ${args["operator"] || "=="} input2;`;
            }
            const returnResult = await VMUtil.runCodeInSandbox({
                code,
                options: {
                    args: args,
                },
            });
            const logMessages = returnResult.logMessages;
            // add to option.log
            logMessages.forEach((msg) => {
                options.log(msg);
            });
            if (returnResult.returnValue) {
                return {
                    returnValues: {},
                    executePort: yesPort,
                };
            }
            return {
                returnValues: {},
                executePort: noPort,
            };
        }
        catch (err) {
            options.log("Error running script");
            options.log(err.message ? err.message : JSON.stringify(err, null, 2));
            throw options.onError(err);
        }
    }
}
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", Promise)
], IfElse.prototype, "run", null);
//# sourceMappingURL=IfElse.js.map