"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.translateToMablscriptStep = translateToMablscriptStep;
exports.createFindDescriptor = createFindDescriptor;
exports.buildFindDescriptor = buildFindDescriptor;
exports.buildFindDescriptorWithShadowParents = buildFindDescriptorWithShadowParents;
exports.translateLocationAssertion = translateLocationAssertion;
exports.translateCookieAssertion = translateCookieAssertion;
exports.translateEmailAssertion = translateEmailAssertion;
exports.injectStep = injectStep;
const mablscriptFind_1 = require("@mablhq/test-model/mablscriptFind");
const uuid_1 = require("uuid");
const step_type_utils_1 = require("../step-type-utils");
const AssertStep_1 = __importDefault(require("../mablscript/canonical/AssertStep"));
const AssertVariableStep_1 = __importDefault(require("../mablscript/canonical/AssertVariableStep"));
const AwaitTabStep_1 = __importDefault(require("../mablscript/canonical/AwaitTabStep"));
const AwaitUploadStep_1 = __importDefault(require("../mablscript/canonical/AwaitUploadStep"));
const ClickAndHoldStep_1 = __importDefault(require("../mablscript/canonical/ClickAndHoldStep"));
const ClickStep_1 = __importDefault(require("../mablscript/canonical/ClickStep"));
const CreateVariableStep_1 = __importDefault(require("../mablscript/canonical/CreateVariableStep"));
const DoubleClickStep_1 = __importDefault(require("../mablscript/canonical/DoubleClickStep"));
const DownloadPdfStep_1 = __importDefault(require("../mablscript/canonical/DownloadPdfStep"));
const DownloadStep_1 = __importDefault(require("../mablscript/canonical/DownloadStep"));
const ElseStep_1 = __importDefault(require("../mablscript/canonical/ElseStep"));
const EndStep_1 = __importDefault(require("../mablscript/canonical/EndStep"));
const EnterTextStep_1 = __importDefault(require("../mablscript/canonical/EnterTextStep"));
const HoverStep_1 = __importDefault(require("../mablscript/canonical/HoverStep"));
const KeyPressStep_1 = __importDefault(require("../mablscript/canonical/KeyPressStep"));
const NavigationStep_1 = __importDefault(require("../mablscript/canonical/NavigationStep"));
const OpenEmailStep_1 = __importDefault(require("../mablscript/canonical/OpenEmailStep"));
const ReleaseStep_1 = __importStar(require("../mablscript/canonical/ReleaseStep"));
const SelectStep_1 = __importDefault(require("../mablscript/canonical/SelectStep"));
const SetFilesStep_1 = __importDefault(require("../mablscript/canonical/SetFilesStep"));
const SwitchContextToStep_1 = __importDefault(require("../mablscript/canonical/SwitchContextToStep"));
const ViewportStep_1 = __importDefault(require("../mablscript/canonical/ViewportStep"));
const VisitUrlStep_1 = __importDefault(require("../mablscript/canonical/VisitUrlStep"));
const WaitStep_1 = __importDefault(require("../mablscript/canonical/WaitStep"));
const AccessibilityCheckStep_1 = __importDefault(require("../mablscript/canonical/AccessibilityCheckStep"));
const RightClickStep_1 = __importDefault(require("../mablscript/canonical/RightClickStep"));
const EnterAuthCodeStep_1 = __importDefault(require("../mablscript/canonical/EnterAuthCodeStep"));
const ClearCookiesStep_1 = __importDefault(require("../mablscript/canonical/ClearCookiesStep"));
const RemoveCookieStep_1 = __importDefault(require("../mablscript/canonical/RemoveCookieStep"));
const SetCookieStep_1 = __importDefault(require("../mablscript/canonical/SetCookieStep"));
const translateToMablStep_1 = require("../translateToMablStep");
const MablscriptImporterUtil_1 = require("../mablscript/MablscriptImporterUtil");
const ExtractDescriptor_1 = require("@mablhq/test-model/types/ExtractDescriptor");
const ConditionDescriptor_1 = require("@mablhq/test-model/types/ConditionDescriptor");
const NavigateStepDescriptor_1 = require("@mablhq/test-model/types/NavigateStepDescriptor");
const mablscript_utils_1 = require("../mablscript/mablscript-utils");
const ExecuteStepGroupStep_1 = __importDefault(require("../mablscript/extended/ExecuteStepGroupStep"));
const listenerTranslators = {
    'accessibility-check': translateAccessibilityCheck,
    'assert-cookie': translateCookieAssertion,
    'clear-cookies': translateClearCookiesAction,
    'assert-email': translateEmailAssertion,
    'assert-variable': translateAssertVariableAction,
    'await-tab': translateAwaitTabAction,
    'await-uploads': translateAwaitUploadAction,
    click: translateClickAction,
    click_hold: translateClickAndHoldAction,
    conditional_else: translateElseStep,
    conditional_end: translateEndStep,
    'double-click': translateDoubleClickAction,
    download: translateDownload,
    'download-pdf': translateDownloadPdfAction,
    hover: translateHoverAction,
    input: translateFinalInputAction,
    keypress: translateKeyPressAction,
    location: translateLocation,
    'mouse-select': translateMouseSelect,
    navigation: translateNavigation,
    'open-email': translateOpenEmail,
    release: translateReleaseAction,
    'enter-auth-code': translateEnterAuthCodeAction,
    'remove-cookie': translateRemoveCookieAction,
    'right-click': translateRightClickAction,
    'set-cookie': translateSetCookieAction,
    'set-files': translateSetFilesAction,
    'set-variable': translateSetVariable,
    'step-group': translateStepGroup,
    'switch-context-to': translateSwitchContextToAction,
    url: translateUrlAction,
    'visit-url': translateVisitUrlAction,
    viewport: translateViewportAction,
    'viewport-assert': translateViewportAssert,
    wait: translateWaitAction,
    'mobile-listener': translateToMablStep_1.translateToMablStepV2,
    'no-op': () => undefined,
};
function translateToMablscriptStep(stepPrototype, elementSelectors) {
    const stepResult = translateToMablscriptStepBeforeShadowParents(stepPrototype, elementSelectors);
    if (!stepResult) {
        return undefined;
    }
    const step = stepResult;
    const stepWithProps = step;
    if (stepPrototype.selectorSearchResult &&
        !stepPrototype.selectorSearchResult.skipped) {
        stepWithProps.selectorSearchResult = stepPrototype.selectorSearchResult;
    }
    if (stepPrototype.shadowParents) {
        stepWithProps.shadowParents = stepPrototype.shadowParents;
    }
    if (stepPrototype.shadowParentsFindingConfidence) {
        if (!stepWithProps.findOptions) {
            stepWithProps.findOptions = {};
        }
        if (stepWithProps.findOptions.trainingHints) {
            stepWithProps.findOptions.trainingHints.shadowParentsFindingConfidence =
                stepPrototype.shadowParentsFindingConfidence;
        }
        else {
            stepWithProps.findOptions.trainingHints = {
                shadowParentsFindingConfidence: stepPrototype.shadowParentsFindingConfidence,
            };
        }
    }
    step.options = Object.assign(step.options ?? {}, stepPrototype.options);
    step.annotations = Object.assign(step.annotations ?? {}, stepPrototype.annotations);
    const sourceEventIdentifier = (0, mablscript_utils_1.maybeGetSourceEventIdentifier)(stepPrototype);
    if (sourceEventIdentifier) {
        step.sourceEventIdentifiers.push(sourceEventIdentifier);
    }
    if (stepWithProps.stepId && !stepWithProps.stepId()) {
        stepWithProps.setStepId?.((0, uuid_1.v4)());
    }
    return step;
}
function translateToMablscriptStepBeforeShadowParents(stepPrototype, elementSelectors) {
    const listener = (0, step_type_utils_1.getStepTypeToListener)(stepPrototype.stepType ?? '');
    const translator = listenerTranslators[listener ?? stepPrototype.listener ?? stepPrototype.stepType ?? ''];
    if (translator) {
        const step = translator(stepPrototype, elementSelectors ?? new mablscriptFind_1.ElementSelectorStore(), stepPrototype.findOptions);
        step?.setStepId(stepPrototype.id ?? (0, uuid_1.v4)());
        return step;
    }
    return undefined;
}
function createFindDescriptor(recordedAction, flowSelectors) {
    let { selectorPrototype } = recordedAction;
    const { elementSelectors, shadowParents } = recordedAction;
    if (!elementSelectors && !selectorPrototype) {
        selectorPrototype = { ...recordedAction };
    }
    const findDescriptor = structuredClone(recordedAction.findDescriptor) ??
        {};
    if ((0, mablscriptFind_1.isWebViewFindElementDescriptor)(findDescriptor)) {
        const nativeWebViewSelector = findDescriptor.findTarget.selector;
        const htmlWebViewElementSelector = findDescriptor.webView.descriptor.findTarget.selector;
        const { selector: nativeSelector } = createAndRegisterSelectorAndShadowParents(flowSelectors, shadowParents ?? [], nativeWebViewSelector, nativeWebViewSelector);
        findDescriptor.findTarget.selector = Array.isArray(nativeSelector)
            ? nativeSelector[0]
            : nativeSelector;
        const { selector: webViewSelector } = createAndRegisterSelectorAndShadowParents(flowSelectors, shadowParents ?? [], htmlWebViewElementSelector, htmlWebViewElementSelector);
        findDescriptor.webView.descriptor.findTarget.selector = Array.isArray(webViewSelector)
            ? webViewSelector[0]
            : webViewSelector;
        return findDescriptor;
    }
    if ((0, mablscriptFind_1.isCustomFindDescriptor)(findDescriptor) ||
        (findDescriptor.type && (0, mablscript_utils_1.isCustomFindType)(findDescriptor.type))) {
        const customFindDescriptor = findDescriptor;
        if (!customFindDescriptor.foundElementSelectors) {
            customFindDescriptor.foundElementSelectors = (0, MablscriptImporterUtil_1.createAndRegisterSelector)(flowSelectors, elementSelectors, selectorPrototype);
        }
        return customFindDescriptor;
    }
    const findOneDescriptor = {
        ...findDescriptor,
        type: 'find_one',
    };
    if (!findOneDescriptor.selector) {
        if (recordedAction.selector) {
            findOneDescriptor.selector = structuredClone(recordedAction.selector);
        }
        else {
            return buildFindDescriptor(flowSelectors, elementSelectors, selectorPrototype, shadowParents);
        }
    }
    const { selector } = createAndRegisterSelectorAndShadowParents(flowSelectors, shadowParents || [], findOneDescriptor.selector, findOneDescriptor.selector);
    findOneDescriptor.selector = Array.isArray(selector) ? selector[0] : selector;
    return findOneDescriptor;
}
function buildFindDescriptor(selectorStore, elementSelectors, selectorPrototype, shadowParents) {
    if (shadowParents?.length) {
        return buildFindDescriptorWithShadowParents(selectorStore, elementSelectors, selectorPrototype, shadowParents);
    }
    const selector = (0, MablscriptImporterUtil_1.createAndRegisterSelector)(selectorStore, elementSelectors, selectorPrototype);
    const targetSelector = Array.isArray(selector) ? selector[0] : selector;
    const ancestorSelector = Array.isArray(selector) && selector.length > 1 ? selector[1] : undefined;
    const findOneDescriptor = {
        type: mablscriptFind_1.FindType.FIND_ONE,
        selector: targetSelector,
        auxiliaryDescriptors: ancestorSelector
            ? [{ selector: ancestorSelector }]
            : [],
    };
    return findOneDescriptor;
}
function createAndRegisterSelectorAndShadowParents(selectorStore, shadowParents, elementSelectors, selectorPrototype) {
    const shadowParentSelectors = createAndRegisterShadowParentSelectors(selectorStore, shadowParents);
    const selectorContext = getContextForSelectorFromShadowParentSelectors(shadowParentSelectors);
    const selector = (0, MablscriptImporterUtil_1.createAndRegisterSelector)(selectorStore, elementSelectors, selectorPrototype, selectorContext);
    return { selector, shadowParentSelectors };
}
function getContextForSelectorFromShadowParentSelectors(shadowParentSelectors) {
    if (shadowParentSelectors?.length) {
        return shadowParentSelectors[shadowParentSelectors.length - 1]?.uuid;
    }
    return undefined;
}
function createAndRegisterShadowParentSelectors(selectorStore, shadowParents) {
    if (!shadowParents?.length) {
        return [];
    }
    return shadowParents.reduce((accumulatedSelectors, currentShadowParent) => {
        const previousParentUuid = getContextForSelectorFromShadowParentSelectors(accumulatedSelectors);
        const currentSelector = (0, MablscriptImporterUtil_1.createAndRegisterSelector)(selectorStore, currentShadowParent, currentShadowParent, previousParentUuid);
        if (Array.isArray(currentSelector)) {
            accumulatedSelectors.push(...currentSelector);
        }
        else {
            accumulatedSelectors.push(currentSelector);
        }
        return accumulatedSelectors;
    }, []);
}
function buildFindDescriptorWithShadowParents(selectorStore, elementSelectors, selectorPrototype, shadowParents) {
    const { selector, shadowParentSelectors } = createAndRegisterSelectorAndShadowParents(selectorStore, shadowParents ?? [], elementSelectors, selectorPrototype);
    const targetSelector = Array.isArray(selector) ? selector[0] : selector;
    const ancestorSelector = Array.isArray(selector) && selector.length > 1 ? selector[1] : undefined;
    const findDescriptor = {
        type: mablscriptFind_1.FindType.FIND_ONE,
        selector: targetSelector,
        auxiliaryDescriptors: ancestorSelector
            ? [{ selector: ancestorSelector }]
            : [],
    };
    findDescriptor.shadowParents = shadowParentSelectors.map((selector) => selector);
    return findDescriptor;
}
function translateUrlAction(recordedAction) {
    if (recordedAction.variable) {
        return new VisitUrlStep_1.default(recordedAction.variable.value, recordedAction.variable);
    }
    return new VisitUrlStep_1.default(recordedAction.url);
}
function translateViewportAction(recordedAction) {
    const sizeArgs = {
        width: recordedAction.size.width,
        height: recordedAction.size.height,
    };
    return new ViewportStep_1.default(sizeArgs);
}
function translateClearCookiesAction() {
    return new ClearCookiesStep_1.default();
}
function translateRemoveCookieAction(recordedAction) {
    return new RemoveCookieStep_1.default({ name: recordedAction.cookie.name });
}
function translateSetCookieAction(recordedAction) {
    const { cookie } = recordedAction;
    return new SetCookieStep_1.default({
        name: cookie.name,
        value: cookie.value,
        domain: cookie.domain,
        path: cookie.path,
        secure: cookie.secure,
        http_only: cookie.httpOnly,
        expiry: cookie.expires,
        same_site: cookie.sameSite,
    });
}
function translateHoverAction(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for HoverStep');
    }
    const findDescriptor = createFindDescriptor(recordedAction, flowSelectors);
    if ((0, mablscriptFind_1.isCustomFindDescriptor)(findDescriptor) ||
        (0, mablscriptFind_1.isFindOneDescriptor)(findDescriptor)) {
        return new HoverStep_1.default(findDescriptor, findOptions);
    }
    throw new Error('Invalid find descriptor type for HoverStep');
}
function translateClickAction(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for ClickStep');
    }
    const findDescriptor = createFindDescriptor(recordedAction, flowSelectors);
    return new ClickStep_1.default(findDescriptor, findOptions);
}
function translateRightClickAction(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for RightClickStep');
    }
    const findDescriptor = createFindDescriptor(recordedAction, flowSelectors);
    return new RightClickStep_1.default(findDescriptor, findOptions);
}
function translateDoubleClickAction(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for DoubleClickStep');
    }
    const findDescriptor = createFindDescriptor(recordedAction, flowSelectors);
    if ((0, mablscriptFind_1.isCustomFindDescriptor)(findDescriptor) ||
        (0, mablscriptFind_1.isFindOneDescriptor)(findDescriptor)) {
        return new DoubleClickStep_1.default(findDescriptor, findOptions);
    }
    throw new Error('Invalid find descriptor type for DoubleClickStep');
}
function translateEnterAuthCodeAction(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for EnterAuthCodeStep');
    }
    const findDescriptor = createFindDescriptor(recordedAction, flowSelectors);
    if ((0, mablscriptFind_1.isCustomFindDescriptor)(findDescriptor) ||
        (0, mablscriptFind_1.isFindOneDescriptor)(findDescriptor)) {
        return new EnterAuthCodeStep_1.default(findDescriptor, findOptions);
    }
    throw new Error('Invalid find descriptor type for EnterAuthCodeStep');
}
function translateLocation(recordedAction) {
    if (recordedAction.assertion) {
        return translateLocationAssertion(recordedAction);
    }
    return undefined;
}
function translateMouseSelect(recordedAction, flowSelectors, findOptions) {
    if (recordedAction.stepType) {
        return transformEditedAssertion(recordedAction);
    }
    if (recordedAction.findDescriptor?.type === 'viewport') {
        return translateViewportAssert(recordedAction);
    }
    if (recordedAction.assertion) {
        return translateMouseAssert(recordedAction, flowSelectors, findOptions);
    }
    return undefined;
}
function translateMouseAssert(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for mouse assertion');
    }
    const findDescriptor = createFindDescriptor(recordedAction, flowSelectors);
    const expectedValue = recordedAction.expectedValue !== undefined
        ? recordedAction.expectedValue
        : recordedAction.expectedText;
    const assertion = recordedAction.assertion;
    if (!assertion) {
        throw new Error('Assertion is required for mouse assertion');
    }
    return new AssertStep_1.default(findDescriptor, {
        selectionType: 'element',
        assertionType: assertion.assertionType,
        assertionTarget: assertion.assertionTarget,
        caseInsensitive: assertion.caseInsensitive,
        onFailure: assertion.onFailure,
        elementScreenshot: assertion.elementScreenshot,
        elementAttrProp: recordedAction.assertedAttrProp,
        extractionType: assertion.extractionType === 'html'
            ? ExtractDescriptor_1.ExtractType.EXTRACT_ATTRIBUTE
            : assertion.extractionType,
        expectedValue,
        variable: recordedAction.variable,
        wrapInConditional: assertion.wrapInConditional,
        wrapInConditionalType: assertion.wrapInConditionalType,
        findOptions,
        aiPrompt: assertion.aiPrompt,
    });
}
function transformEditedAssertion(recordedEdit) {
    const { findDescriptor, selectionType, assertionType, assertionTarget, caseInsensitive, onFailure, elementScreenshot, elementAttrProp, expectedValue, extractionType, variable, wrapInConditional, wrapInConditionalType, findOptions, aiPrompt, } = recordedEdit;
    if (!findDescriptor) {
        throw new Error('findDescriptor is required for edited assertion');
    }
    return new AssertStep_1.default(findDescriptor, {
        selectionType,
        assertionType,
        assertionTarget,
        caseInsensitive,
        onFailure,
        elementScreenshot,
        elementAttrProp,
        expectedValue,
        extractionType,
        variable,
        wrapInConditional,
        wrapInConditionalType,
        findOptions,
        aiPrompt,
    });
}
function translateViewportAssert(recordedAction) {
    const findDescriptor = {
        type: 'viewport',
    };
    const assertion = recordedAction.assertion;
    if (!assertion) {
        throw new Error('Assertion is required for viewport assertion');
    }
    return new AssertStep_1.default(findDescriptor, {
        selectionType: 'viewport',
        assertionType: ConditionDescriptor_1.AssertionConditionField.AIPrompt,
        assertionTarget: assertion.assertionTarget,
        onFailure: assertion.onFailure,
        extractionType: ExtractDescriptor_1.ExtractType.EXTRACT_PROMPT,
        wrapInConditional: assertion.wrapInConditional,
        wrapInConditionalType: assertion.wrapInConditionalType,
        aiPrompt: assertion.aiPrompt,
    });
}
function translateNavigation(recordedAction) {
    switch (recordedAction.type) {
        case 'typed_url':
            return new VisitUrlStep_1.default(recordedAction.url);
        case 'reload':
            return new NavigationStep_1.default(NavigateStepDescriptor_1.NavigationTypes.reload);
    }
    return undefined;
}
function translateVisitUrlAction(recordedAction) {
    return new VisitUrlStep_1.default(recordedAction.url, recordedAction.variable);
}
function translateDownload(recordedAction) {
    if (recordedAction.downloadForm) {
        const { detectedProps, assertions, aiPrompt, fileNameMatchMode } = recordedAction.downloadForm;
        return new DownloadStep_1.default({
            detectedProperties: detectedProps,
            assertions,
            aiPrompt,
            fileNameMatchMode,
        });
    }
    else if (recordedAction.detectedDownloadEvent) {
        return new DownloadStep_1.default({
            detectedProperties: recordedAction.detectedDownloadEvent,
        });
    }
    return undefined;
}
function translateDownloadPdfAction(recordedAction) {
    if (recordedAction.downloadForm) {
        const { detectedProps: detectedProperties, assertions, awaitParams: awaitParameters, aiPrompt, } = recordedAction.downloadForm;
        return new DownloadPdfStep_1.default({
            detectedProperties,
            assertions,
            awaitParameters,
            aiPrompt,
        });
    }
    else if (recordedAction.detectedDownloadEvent) {
        return new DownloadPdfStep_1.default({
            detectedProperties: recordedAction.detectedDownloadEvent,
            awaitParameters: recordedAction.detectedDownloadEvent.awaitParameters,
        });
    }
    return undefined;
}
function translateLocationAssertion(recordedAction) {
    const findDescriptor = { type: 'location', url: recordedAction.url };
    const assertion = recordedAction.assertion;
    if (!assertion) {
        throw new Error('Assertion is required for location assertion');
    }
    return new AssertStep_1.default(findDescriptor, {
        selectionType: 'location',
        assertionType: assertion.assertionType,
        assertionTarget: assertion.assertionTarget,
        caseInsensitive: assertion.caseInsensitive,
        onFailure: assertion.onFailure,
        elementScreenshot: assertion.elementScreenshot,
        elementAttrProp: recordedAction.assertedAttrProp,
        expectedValue: recordedAction.expectedValue,
        variable: recordedAction.variable,
        wrapInConditional: assertion.wrapInConditional,
        wrapInConditionalType: assertion.wrapInConditionalType,
    });
}
function translateCookieAssertion(recordedAction) {
    const assertion = recordedAction.assertion;
    if (!assertion) {
        throw new Error('Assertion is required for cookie assertion');
    }
    return new AssertStep_1.default(recordedAction.findDescriptor, {
        assertionTarget: assertion.assertionTarget,
        assertionType: assertion.assertionType,
        caseInsensitive: assertion.caseInsensitive,
        elementAttrProp: recordedAction.assertedAttrProp,
        elementScreenshot: assertion.elementScreenshot,
        expectedValue: recordedAction.expectedValue,
        onFailure: assertion.onFailure,
        selectionType: 'cookie',
        variable: recordedAction.variable,
        wrapInConditional: assertion.wrapInConditional,
        wrapInConditionalType: assertion.wrapInConditionalType,
    });
}
function translateEmailAssertion(recordedAction) {
    const assertion = recordedAction.assertion;
    if (!assertion) {
        throw new Error('Assertion is required for email assertion');
    }
    return new AssertStep_1.default(recordedAction.findDescriptor, {
        assertionTarget: assertion.assertionTarget,
        selectionType: 'email',
        assertionType: assertion.assertionType,
        caseInsensitive: assertion.caseInsensitive,
        elementAttrProp: recordedAction.assertedAttrProp,
        elementScreenshot: assertion.elementScreenshot,
        expectedValue: recordedAction.expectedValue,
        onFailure: assertion.onFailure,
        variable: recordedAction.variable,
        wrapInConditional: assertion.wrapInConditional,
        wrapInConditionalType: assertion.wrapInConditionalType,
    });
}
function translateSetFilesAction(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for SetFilesStep');
    }
    const findDescriptor = createFindDescriptor(recordedAction, flowSelectors);
    if ((0, mablscriptFind_1.isCustomFindDescriptor)(findDescriptor) ||
        (0, mablscriptFind_1.isFindOneDescriptor)(findDescriptor)) {
        return new SetFilesStep_1.default(findDescriptor, recordedAction.files ?? [], findOptions);
    }
    throw new Error('Invalid find descriptor type for SetFilesStep');
}
function translateAwaitUploadAction() {
    return new AwaitUploadStep_1.default();
}
function translateFinalInputAction(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for input action');
    }
    const findDescriptor = createFindDescriptor(recordedAction, flowSelectors);
    let targetSelector;
    if ((0, mablscriptFind_1.isFindOneDescriptor)(findDescriptor)) {
        targetSelector =
            findDescriptor.selector ??
                (recordedAction.elementSelectors
                    ? (0, mablscriptFind_1.getTargetSelector)(recordedAction.elementSelectors)
                    : undefined);
    }
    else if ((0, mablscriptFind_1.isCustomFindDescriptor)(findDescriptor)) {
        targetSelector = recordedAction.elementSelectors
            ? (0, mablscriptFind_1.getTargetSelector)(recordedAction.elementSelectors)
            : undefined;
    }
    else {
        targetSelector = recordedAction.elementSelectors
            ? (0, mablscriptFind_1.getTargetSelector)(recordedAction.elementSelectors)
            : undefined;
    }
    if (targetSelector?.tag_name?.toLowerCase() === 'select' ||
        ['any', 'exact'].includes(recordedAction?.selectOptionType ?? '')) {
        const selectionSelector = recordedAction.selectionSelector
            ? recordedAction.selectionSelector
            : createSelectionSelector(recordedAction);
        if ((0, mablscriptFind_1.isCustomFindDescriptor)(findDescriptor) ||
            (0, mablscriptFind_1.isFindOneDescriptor)(findDescriptor)) {
            return new SelectStep_1.default(findDescriptor, selectionSelector, recordedAction.selectOptionType, findOptions, recordedAction.variable, recordedAction.isPattern);
        }
        throw new Error('Invalid find descriptor type for SelectStep');
    }
    else {
        if ((0, mablscriptFind_1.isCustomFindDescriptor)(findDescriptor) ||
            (0, mablscriptFind_1.isFindOneDescriptor)(findDescriptor)) {
            return new EnterTextStep_1.default(findDescriptor, recordedAction.inputValue, recordedAction.variable, findOptions, {
                enterTextMode: recordedAction.enterTextMode,
                doNotRetry: recordedAction.doNotRetry,
            });
        }
        throw new Error('Invalid find descriptor type for EnterTextStep');
    }
}
function translateKeyPressAction(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for KeyPressStep');
    }
    const findDescriptor = createFindDescriptor(recordedAction, flowSelectors);
    if ((0, mablscriptFind_1.isCustomFindDescriptor)(findDescriptor) ||
        (0, mablscriptFind_1.isFindOneDescriptor)(findDescriptor)) {
        if (!recordedAction.keyInfoArray) {
            throw new Error('keyInfoArray is required for KeyPressStep');
        }
        return new KeyPressStep_1.default(findDescriptor, recordedAction.keyInfoArray, findOptions);
    }
    throw new Error('Invalid find descriptor type for KeyPressStep');
}
function translateWaitAction(action) {
    if (action.time === undefined) {
        throw new Error('time is required for WaitStep');
    }
    return new WaitStep_1.default(action.time * 1000);
}
function isElementPropertyVariable(variable) {
    return variable !== undefined && 'target' in variable;
}
function isCookieFindDescriptor(descriptor) {
    return descriptor && descriptor.type === 'cookie';
}
function translateSwitchContextToAction(action, flowSelectors, findOptions) {
    if (action.frameId !== 0) {
        if (!flowSelectors) {
            throw new Error('ElementSelectorStore is required for frame switching');
        }
        return new SwitchContextToStep_1.default(createFindDescriptor(action, flowSelectors), findOptions);
    }
    else if (action.tabId !== action.originatingTabId) {
        return new SwitchContextToStep_1.default(action.findDescriptor, findOptions);
    }
    return new SwitchContextToStep_1.default(undefined);
}
function translateAwaitTabAction(action) {
    if (!action.tabSelector) {
        throw new Error('tabSelector is required for AwaitTabStep');
    }
    return new AwaitTabStep_1.default(action.tabSelector);
}
function createSelectionSelector(action) {
    const rawIndex = action.selectedIndex ?? action.selectionSelector?.index;
    const index = rawIndex !== undefined ? Number(rawIndex) : undefined;
    return {
        index,
        value: (action.inputValue ?? action.selectionSelector?.value),
        text: action.selectedText ?? action.selectionSelector?.text,
        selector_type: 'select',
        uuid: (0, uuid_1.v4)(),
    };
}
function translateSetVariable(action, flowSelectors, findOptionsParam) {
    let findDescriptor = action.findDescriptor;
    let findOptions = action.findOptions ?? findOptionsParam;
    if (!findDescriptor && isElementPropertyVariable(action.variable)) {
        findDescriptor = createFindDescriptor(action.variable.target, flowSelectors);
    }
    if (!findOptions && isElementPropertyVariable(action.variable)) {
        findOptions = action.variable.target.findOptions;
    }
    const variable = action.variable;
    if (variable?.variableType === mablscriptFind_1.VariableType.JAVASCRIPT) {
        const { snippet, parameterOverrides } = action;
        if (!snippet) {
            throw new Error('snippet is required for JavaScript variable');
        }
        const parameterized = !!snippet.parameters;
        const reusable = !!(snippet.id && snippet.invariant_id);
        if (!parameterized) {
            if (reusable) {
                if (!snippet.invariant_id) {
                    throw new Error('snippet.invariant_id is required for reusable JavaScript variable');
                }
                variable.javaScript = {
                    snippetInvariantId: snippet.invariant_id,
                };
                variable.snippet = snippet;
            }
            else {
                variable.javaScript = {
                    encodedJS: snippet.body,
                };
                variable.snippet = {
                    body: snippet.body,
                    snippet_type: 'javascript',
                };
            }
        }
        else {
            if (reusable) {
                if (!snippet.id || !snippet.invariant_id) {
                    throw new Error('snippet.id and snippet.invariant_id are required for reusable parameterized JavaScript variable');
                }
                variable.javaScript = {
                    snippetId: snippet.id,
                    snippetInvariantId: snippet.invariant_id,
                    parameterOverrides: parameterOverrides ?? [],
                };
                variable.snippet = snippet;
            }
            else {
                const inlineSnippetKeys = [
                    'snippet_type',
                    'body',
                    'parameters',
                    'name',
                    'description',
                ];
                Object.keys(snippet).forEach((key) => {
                    if (!inlineSnippetKeys.includes(key)) {
                        delete snippet[key];
                    }
                });
                variable.javaScript = {
                    inlineSnippet: snippet,
                    parameterOverrides: parameterOverrides ?? [],
                };
                variable.snippet = snippet;
            }
        }
    }
    if (!variable) {
        throw new Error('variable is required for CreateVariableStep');
    }
    return new CreateVariableStep_1.default(variable, findDescriptor &&
        ((0, mablscriptFind_1.isCustomFindDescriptor)(findDescriptor) ||
            (0, mablscriptFind_1.isFindOneDescriptor)(findDescriptor) ||
            isCookieFindDescriptor(findDescriptor))
        ? findDescriptor
        : undefined, findOptions);
}
function translateElseStep() {
    return new ElseStep_1.default();
}
function translateEndStep() {
    return new EndStep_1.default();
}
function translateAssertVariableAction(recordedAction) {
    const assertion = recordedAction.assertion;
    if (!assertion) {
        throw new Error('assertion is required for AssertVariableStep');
    }
    return new AssertVariableStep_1.default({
        assertionType: assertion.assertionType,
        onFailure: assertion.onFailure,
        expectedValue: recordedAction.expectedValue,
        selectionType: 'variable',
        variable: recordedAction.variable,
        wrapInConditional: assertion.wrapInConditional,
        wrapInConditionalType: assertion.wrapInConditionalType,
        caseInsensitive: assertion.caseInsensitive,
    });
}
function translateOpenEmail(recordedAction) {
    if (!recordedAction.findDescriptor ||
        !(0, mablscriptFind_1.isEmailFindDescriptor)(recordedAction.findDescriptor)) {
        throw new Error('Invalid find descriptor for OpenEmailStep - must be EmailFindDescriptor');
    }
    return new OpenEmailStep_1.default(recordedAction.findDescriptor, recordedAction.tabUuid ?? '');
}
function translateClickAndHoldAction(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for ClickAndHoldStep');
    }
    const find = createFindDescriptor(recordedAction, flowSelectors);
    if ((0, mablscriptFind_1.isCustomFindDescriptor)(find) || (0, mablscriptFind_1.isFindOneDescriptor)(find)) {
        return new ClickAndHoldStep_1.default(find, findOptions, recordedAction.isHtml5 ?? false);
    }
    throw new Error('Invalid find descriptor type for ClickAndHoldStep');
}
function translateReleaseAction(recordedAction, flowSelectors, findOptions) {
    if (!flowSelectors) {
        throw new Error('ElementSelectorStore is required for ReleaseStep');
    }
    const find = createFindDescriptor(recordedAction, flowSelectors);
    if ((0, mablscriptFind_1.isCustomFindDescriptor)(find) || (0, mablscriptFind_1.isFindOneDescriptor)(find)) {
        if (!recordedAction.releaseArgs) {
            throw new Error('releaseArgs is required for ReleaseStep');
        }
        const { isHtml5, steps } = recordedAction.releaseArgs;
        if (isHtml5) {
            return new ReleaseStep_1.default(find, findOptions, {
                isHtml5: true,
            });
        }
        return new ReleaseStep_1.default(find, findOptions, {
            isHtml5: false,
            steps: steps ?? ReleaseStep_1.DEFAULT_RELEASE_STEPS,
        });
    }
    throw new Error('Invalid find descriptor type for ReleaseStep');
}
function translateAccessibilityCheck(recordedAction, flowSelectors, findOptions) {
    let find;
    if (recordedAction.findDescriptor) {
        if (!flowSelectors) {
            throw new Error('ElementSelectorStore is required when findDescriptor is present');
        }
        find = createFindDescriptor(recordedAction, flowSelectors);
    }
    let checkConfig;
    if (recordedAction.tags ||
        recordedAction.rules ||
        recordedAction.disabledRules ||
        recordedAction.failOn ||
        recordedAction.bypassCors ||
        recordedAction.runInMainFrame ||
        recordedAction.disabledRulesOnIframes) {
        checkConfig = {
            tags: recordedAction.tags,
            rules: recordedAction.rules,
            disabledRules: recordedAction.disabledRules,
            failOn: recordedAction.failOn,
            bypassCors: recordedAction.bypassCors,
            runInMainFrame: recordedAction.runInMainFrame,
            disabledRulesOnIframes: recordedAction.disabledRulesOnIframes,
        };
    }
    return new AccessibilityCheckStep_1.default(checkConfig, find && ((0, mablscriptFind_1.isCustomFindDescriptor)(find) || (0, mablscriptFind_1.isFindOneDescriptor)(find))
        ? find
        : undefined, findOptions);
}
function translateStepGroup(action) {
    return new ExecuteStepGroupStep_1.default(action.steps ?? [], action.description);
}
function injectStep(step, recordedSteps, index, operation) {
    if (operation === 'replace') {
        try {
            const currentStep = recordedSteps.steps[index];
            if (currentStep?.id) {
                step.setStepId(currentStep?.id);
            }
        }
        catch (error) {
            console.error('Could not persist the step ID when editing a step', error);
        }
        recordedSteps.steps.splice(index, 1, step);
        return index;
    }
    else if (step.canBeCollapsed &&
        step.isCollapsible?.(recordedSteps.steps[index - 1])) {
        step.mergePreviousStep?.(recordedSteps.steps[index - 1]);
        recordedSteps.steps.splice(index - 1, 1, step);
        return index - 1;
    }
    else if (step.canRemovePrevious &&
        step.shouldRemovePrevious?.(recordedSteps.steps[index - 1])) {
        recordedSteps.steps.splice(index - 1, 1);
        return index - 1;
    }
    recordedSteps.steps.splice(index, 0, step);
    return index;
}
