"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IfConditionStep = void 0;
exports.isIfConditionStep = isIfConditionStep;
const ConditionAction_1 = require("../actions/ConditionAction");
const GetVariableValue_1 = require("../actions/GetVariableValue");
const AssertStep_1 = require("./AssertStep");
const FindAction_1 = require("../actions/FindAction");
const MablAction_1 = require("../MablAction");
const MablStepV2_1 = require("../MablStepV2");
const ExtractAction_1 = require("../actions/ExtractAction");
const ActionBuilderUtils_1 = require("../actions/ActionBuilderUtils");
const mablscriptFind_1 = require("../mablscriptFind");
const JavaScriptAction_1 = require("../actions/JavaScriptAction");
const GetUrlAction_1 = require("../actions/GetUrlAction");
const ConditionDescriptor_1 = require("../types/ConditionDescriptor");
const GetViewportAction_1 = require("../actions/GetViewportAction");
const MobileFindAction_1 = require("../mobile/steps/actions/MobileFindAction");
const CountAction_1 = require("../actions/CountAction");
class IfConditionStep extends MablStepV2_1.MablStepV2 {
    static stepName = 'If';
    static actionCode = 'conditional_if';
    static mablScriptStepNames = [IfConditionStep.actionCode];
    static yamlMablScriptNames = [IfConditionStep.stepName];
    primaryAction;
    conditionAction;
    extractAction;
    countAction;
    observationScope;
    constructor(stepName, actionCode, descriptor, stepActions) {
        super(stepName, descriptor, actionCode);
        this.primaryAction = stepActions.primaryAction;
        this.conditionAction = stepActions.conditionAction;
        this.extractAction = stepActions.extractAction;
        this.countAction = stepActions.countAction;
        this.observationScope = descriptor.observationScope;
        const actions = [this.primaryAction];
        if (this.extractAction) {
            actions.push(this.extractAction);
        }
        if (this.countAction) {
            actions.push(this.countAction);
        }
        if (this.conditionAction) {
            actions.push(this.conditionAction);
        }
        this.actions = actions;
    }
    static fromLegacyMablscript(_args, actions) {
        const validatedActions = IfConditionStep.validateAndParseActions(actions);
        const stepDescriptor = IfConditionStep.buildDescriptor(validatedActions);
        const step = new IfConditionStep(IfConditionStep.stepName, IfConditionStep.actionCode, stepDescriptor, validatedActions);
        step.actions = actions;
        return step;
    }
    static validateAndParseActions(actions) {
        const candidatePrimaryActions = actions.filter((action) => action instanceof FindAction_1.FindAction ||
            action instanceof MobileFindAction_1.MobileFindAction ||
            action instanceof GetVariableValue_1.GetVariableValue ||
            action instanceof GetUrlAction_1.GetUrlAction ||
            action instanceof JavaScriptAction_1.JavaScriptAction);
        if (candidatePrimaryActions.length > 1) {
            throw new Error(`Too many primary actions. Only one primary action is allowed of: Find, Get Url, Get Variable, or Javascript actions`);
        }
        const conditionAction = actions.find((action) => action instanceof ConditionAction_1.ConditionAction);
        const extractAction = actions.find((action) => action instanceof ExtractAction_1.ExtractAction);
        const countAction = actions.find((action) => action instanceof CountAction_1.CountAction);
        let primaryAction;
        if (candidatePrimaryActions[0] === undefined) {
            if (conditionAction !== undefined &&
                (0, ConditionDescriptor_1.isAIPromptCondition)(conditionAction.conditionDescriptor)) {
                primaryAction = new GetViewportAction_1.GetViewportAction();
            }
            else {
                throw new Error(`At least one primary action is required: Find, Get Url, Get Variable, or Javascript action.`);
            }
        }
        else {
            primaryAction = candidatePrimaryActions[0];
        }
        return { primaryAction, conditionAction, extractAction, countAction };
    }
    static buildDescriptor(validatedActions) {
        const conditionDescriptor = validatedActions.conditionAction !== undefined
            ? validatedActions.conditionAction?.conditionDescriptor
            : { conditionType: ConditionDescriptor_1.ConditionType.Truthy };
        const target = validatedActions.primaryAction.toDescriptor();
        const count = validatedActions.countAction?.countDescriptor;
        const extract = validatedActions.extractAction?.toDescriptor();
        return {
            target,
            extract,
            condition: conditionDescriptor,
            count,
            onFailure: AssertStep_1.OnFailure.FailImmediately,
            actionCode: IfConditionStep.actionCode,
        };
    }
    getStepName() {
        return IfConditionStep.stepName;
    }
    static getActionsFromYamlForCondition(stepArgs) {
        const actions = [];
        const isNewFormat = stepArgs.target && typeof stepArgs.condition === 'object';
        if (isNewFormat) {
            if (stepArgs.target) {
                if (stepArgs.target.javaScript) {
                    actions.push(JavaScriptAction_1.JavaScriptAction.fromYaml(stepArgs.target));
                }
                else {
                    const primaryAction = ActionBuilderUtils_1.ActionBuilderUtils.buildPrimaryActionFromTarget(stepArgs.target);
                    actions.push(primaryAction);
                }
            }
            if (stepArgs.extract) {
                const extractAction = ActionBuilderUtils_1.ActionBuilderUtils.buildExtractActionFromDescriptor(stepArgs.extract);
                if (extractAction) {
                    actions.push(extractAction);
                }
            }
            if (stepArgs.count) {
                const countAction = ActionBuilderUtils_1.ActionBuilderUtils.buildCountActionFromDescriptor(stepArgs.count);
                if (countAction) {
                    actions.push(countAction);
                }
            }
            if (stepArgs.condition) {
                if (stepArgs.condition.conditionType === 'truthy') {
                }
                else {
                    const conditionAction = ActionBuilderUtils_1.ActionBuilderUtils.buildConditionActionFromDescriptor(stepArgs.condition, { caseInsensitive: stepArgs.condition.caseInsensitive });
                    actions.push(conditionAction);
                }
            }
            return actions;
        }
        if (stepArgs.find) {
            if ((0, mablscriptFind_1.isMobileFindDescriptor)(stepArgs.find)) {
                actions.push(MobileFindAction_1.MobileFindAction.fromDescriptor(stepArgs.find));
            }
            else {
                actions.push(FindAction_1.FindAction.findActionFromStepArgs(stepArgs));
            }
        }
        else if (stepArgs.selector) {
            if ((0, mablscriptFind_1.isMobileFindSpecification)(stepArgs)) {
                const findAction = MobileFindAction_1.MobileFindAction.fromDescriptor({
                    findTarget: { selector: stepArgs.selector },
                    findType: mablscriptFind_1.FindType.FIND_ONE,
                });
                actions.push(findAction);
            }
            else {
                const findAction = FindAction_1.FindAction.findActionFromStepArgs(stepArgs);
                actions.push(findAction);
            }
        }
        if (stepArgs.attribute) {
            const extractArgs = stepArgs.metadata
                ? [stepArgs.attribute, stepArgs.metadata]
                : [stepArgs.attribute];
            actions.push(new ExtractAction_1.ExtractAction('extract_attribute', extractArgs));
        }
        if (stepArgs.variableName) {
            actions.push(GetVariableValue_1.GetVariableValue.buildAction(stepArgs.variableName));
        }
        if (stepArgs.snippet) {
            actions.push(JavaScriptAction_1.JavaScriptAction.fromYaml(stepArgs.snippet));
        }
        if (stepArgs.condition) {
            const conditionStepName = stepArgs.condition;
            const conditionType = ConditionDescriptor_1.AssertionStepNameToField[conditionStepName];
            if (conditionType === 'ai_prompt') {
                actions.push(new ConditionAction_1.ConditionAction(this.getConditionActionNameForConditionType(conditionType), [
                    stepArgs.aiPrompt?.userPrompt ?? stepArgs.userPrompt,
                    {
                        metaPrompt: stepArgs.aiPrompt?.metaPrompt ?? stepArgs.metaPrompt,
                        criteria: stepArgs.aiPrompt?.criteria,
                    },
                ]));
            }
            else {
                actions.push(new ConditionAction_1.ConditionAction(this.getConditionActionNameForConditionType(conditionType), [conditionType, stepArgs.conditionValue, stepArgs.conditionOptions]));
            }
        }
        return actions;
    }
    static getConditionActionNameForConditionType(conditionType) {
        if (conditionType === 'present' || conditionType === 'not_present') {
            return 'evaluate_presence';
        }
        else if (conditionType === 'ai_prompt') {
            return 'evaluate_ai_prompt';
        }
        return 'evaluate_condition';
    }
    static fromYaml(_stepName, stepArgs) {
        const actions = IfConditionStep.getActionsFromYamlForCondition(stepArgs);
        const validatedActions = IfConditionStep.validateAndParseActions(actions);
        const stepDescriptor = IfConditionStep.buildDescriptor(validatedActions);
        if (stepArgs.observationScope) {
            stepDescriptor.observationScope =
                stepArgs.observationScope;
        }
        const step = new IfConditionStep(IfConditionStep.stepName, IfConditionStep.actionCode, stepDescriptor, validatedActions);
        step.setStepId(stepArgs.id);
        if (stepArgs.annotation) {
            step.setAnnotation(stepArgs.annotation);
        }
        if (stepArgs.description) {
            step.setDescription(stepArgs.description);
        }
        if (stepArgs.disabled) {
            step.setDisabled(stepArgs.disabled);
        }
        return step;
    }
    toMablscript() {
        const actions = [
            this.primaryAction,
            this.extractAction,
            this.conditionAction,
        ].filter(Boolean);
        return `${actions.reduce((mablscript, action) => `${mablscript}${action?.toMablscript()}.`, '')}conditional_if()`;
    }
    getInputVariables() {
        const actions = [
            this.primaryAction,
            this.extractAction,
            this.conditionAction,
        ].filter(Boolean);
        return (0, MablAction_1.distinctStrings)(actions.flatMap((action) => action?.getInputVariables() ?? []));
    }
    stepDescription() {
        return 'IF condition';
    }
    static create(descriptor, stepActions) {
        if (!stepActions) {
            throw new Error('stepActions is required for IfConditionStep.create');
        }
        descriptor.id = descriptor.id ?? MablStepV2_1.MablStepV2.generateStepId();
        return new IfConditionStep(IfConditionStep.stepName, IfConditionStep.actionCode, descriptor, stepActions);
    }
}
exports.IfConditionStep = IfConditionStep;
function isIfConditionStep(value) {
    return (value?.getStepName &&
        value?.getStepName() === IfConditionStep.yamlMablScriptNames[0]);
}
