"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CreateVariableStep = void 0;
exports.isCreateVariableStep = isCreateVariableStep;
const mablscriptFind_1 = require("../mablscriptFind");
const CountAction_1 = require("../actions/CountAction");
const ExtractAction_1 = require("../actions/ExtractAction");
const FindAction_1 = require("../actions/FindAction");
const GenerateEmailAddressAction_1 = require("../actions/GenerateEmailAddressAction");
const GenerateRandomStringAction_1 = require("../actions/GenerateRandomStringAction");
const JavaScriptAction_1 = require("../actions/JavaScriptAction");
const MablStepV2_1 = require("../MablStepV2");
const CreateVariableStepDescriptor_1 = require("../types/CreateVariableStepDescriptor");
const MablSymbol_1 = require("../MablSymbol");
class CreateVariableStep extends MablStepV2_1.MablStepV2 {
    static stepName = 'CreateVariable';
    static actionCode = 'as';
    static mablScriptStepNames = [CreateVariableStep.actionCode];
    static yamlMablScriptNames = [
        CreateVariableStep.stepName,
        'GenerateEmailAddress',
    ];
    variableName;
    generationType;
    constructor(descriptor) {
        super(CreateVariableStep.stepName, descriptor, CreateVariableStep.actionCode);
        if (!this.isValidDescriptor(this.descriptor)) {
            throw new Error(`${CreateVariableStep.stepName}: descriptor.name must be a string and descriptor.generator must be defined with a type`);
        }
        this.variableName = this.descriptor.name;
        this.generationType = this.descriptor.generator.type;
        this.actions = this.buildActions(this.descriptor);
    }
    isValidDescriptor(value) {
        return (typeof value.name === 'string' && value.generator?.type !== undefined);
    }
    getStepName() {
        return CreateVariableStep.stepName;
    }
    static buildStepDescriptor(variableName, generationType, actions) {
        switch (generationType) {
            case CreateVariableStepDescriptor_1.VariableGenerator.ATTRIBUTE:
                const findAction = actions[0];
                const extractAction = actions[1];
                const find = findAction.toDescriptor();
                return {
                    name: variableName,
                    generator: {
                        type: CreateVariableStepDescriptor_1.VariableGenerator.ATTRIBUTE,
                        attribute: extractAction.extractionAttribute,
                        find,
                    },
                    find,
                    actionCode: CreateVariableStep.actionCode,
                };
            case CreateVariableStepDescriptor_1.VariableGenerator.ELEMENT_COUNT:
                const countFindAction = actions[0];
                const countFind = countFindAction.toDescriptor();
                return {
                    find: countFind,
                    name: variableName,
                    generator: {
                        type: CreateVariableStepDescriptor_1.VariableGenerator.ELEMENT_COUNT,
                        find: countFind,
                    },
                    actionCode: CreateVariableStep.actionCode,
                };
            case CreateVariableStepDescriptor_1.VariableGenerator.EMAIL:
                return {
                    name: variableName,
                    generator: { type: CreateVariableStepDescriptor_1.VariableGenerator.EMAIL },
                    actionCode: CreateVariableStep.actionCode,
                };
            case CreateVariableStepDescriptor_1.VariableGenerator.JAVASCRIPT:
                const jsAction = actions[0];
                return {
                    name: variableName,
                    generator: {
                        type: CreateVariableStepDescriptor_1.VariableGenerator.JAVASCRIPT,
                        javaScript: jsAction.toDescriptor().javaScript,
                    },
                    actionCode: CreateVariableStep.actionCode,
                };
            case CreateVariableStepDescriptor_1.VariableGenerator.PATTERN:
                const patternAction = actions[0];
                return {
                    name: variableName,
                    generator: {
                        type: CreateVariableStepDescriptor_1.VariableGenerator.PATTERN,
                        pattern: patternAction.generateString,
                    },
                    actionCode: CreateVariableStep.actionCode,
                };
            case CreateVariableStepDescriptor_1.VariableGenerator.COOKIE_ATTRIBUTE:
                const cookieFindAction = actions[0];
                const cookieExtractAction = actions[1];
                const cookieFind = cookieFindAction.toDescriptor();
                return {
                    name: variableName,
                    generator: {
                        type: CreateVariableStepDescriptor_1.VariableGenerator.COOKIE_ATTRIBUTE,
                        cookieSelector: cookieFind.findTarget,
                        attribute: cookieExtractAction.extractionAttribute,
                    },
                    find: cookieFind,
                    actionCode: CreateVariableStep.actionCode,
                };
            default:
                throw new Error(`Unsupported variable generation type: ${generationType}`);
        }
    }
    buildActions(descriptor) {
        const actions = [];
        switch (descriptor.generator.type) {
            case CreateVariableStepDescriptor_1.VariableGenerator.ATTRIBUTE:
                if ('find' in descriptor) {
                    const attrGenerator = descriptor.generator;
                    actions.push(FindAction_1.FindAction.findActionFromStepArgs(descriptor));
                    actions.push(new ExtractAction_1.ExtractAction('extract_attribute', [attrGenerator.attribute]));
                }
                break;
            case CreateVariableStepDescriptor_1.VariableGenerator.ELEMENT_COUNT:
                if ('find' in descriptor) {
                    const findDescriptor = descriptor.find;
                    actions.push(new FindAction_1.FindAction('find_all', [
                        findDescriptor.findTarget,
                        findDescriptor.foundElementSelectors,
                        findDescriptor.findOptions,
                    ]));
                    actions.push(new CountAction_1.CountAction('count', []));
                }
                break;
            case CreateVariableStepDescriptor_1.VariableGenerator.EMAIL:
                actions.push(new GenerateEmailAddressAction_1.GenerateEmailAddressAction('generate_email_address', []));
                break;
            case CreateVariableStepDescriptor_1.VariableGenerator.JAVASCRIPT:
                const jsGenerator = descriptor.generator;
                actions.push(JavaScriptAction_1.JavaScriptAction.fromDescriptor(jsGenerator));
                break;
            case CreateVariableStepDescriptor_1.VariableGenerator.PATTERN:
                const patternGenerator = descriptor.generator;
                actions.push(new GenerateRandomStringAction_1.GenerateRandomStringAction('generate_random_string', [
                    patternGenerator.pattern,
                ]));
                break;
            case CreateVariableStepDescriptor_1.VariableGenerator.COOKIE_ATTRIBUTE:
                if ('find' in descriptor) {
                    const cookieGenerator = descriptor.generator;
                    actions.push(new FindAction_1.FindAction('find_cookie', [cookieGenerator.cookieSelector]));
                    actions.push(new ExtractAction_1.ExtractAction('extract_attribute', [cookieGenerator.attribute]));
                }
                break;
            default:
                throw new Error(`Unsupported variable generation type: ${descriptor.generator.type}`);
        }
        return actions;
    }
    static fromYaml(_stepName, stepArgs) {
        return new CreateVariableStep(stepArgs);
    }
    static fromLegacyMablscript(args, actions) {
        const variableName = (0, MablSymbol_1.isMablSymbolObject)(args[0])
            ? (0, MablSymbol_1.formatSymbol)(args[0])
            : args[0];
        const generationType = CreateVariableStep.calculateGenerationType(actions);
        const stepDescriptor = CreateVariableStep.buildStepDescriptor(variableName, generationType, actions);
        const step = new CreateVariableStep(stepDescriptor);
        return step;
    }
    static calculateGenerationType(actions) {
        if (actions.length === 2 && actions[0] instanceof FindAction_1.FindAction) {
            if (actions[0].findDescriptor.findType === mablscriptFind_1.FindType.FIND_COOKIE) {
                return CreateVariableStepDescriptor_1.VariableGenerator.COOKIE_ATTRIBUTE;
            }
            if (actions[1] instanceof ExtractAction_1.ExtractAction) {
                return CreateVariableStepDescriptor_1.VariableGenerator.ATTRIBUTE;
            }
            else if (actions[1] instanceof CountAction_1.CountAction) {
                return CreateVariableStepDescriptor_1.VariableGenerator.ELEMENT_COUNT;
            }
        }
        else if (actions.length === 1 &&
            actions[0] instanceof GenerateEmailAddressAction_1.GenerateEmailAddressAction) {
            return CreateVariableStepDescriptor_1.VariableGenerator.EMAIL;
        }
        else if (actions.length === 1 && actions[0] instanceof JavaScriptAction_1.JavaScriptAction) {
            return CreateVariableStepDescriptor_1.VariableGenerator.JAVASCRIPT;
        }
        else if (actions.length === 1 &&
            actions[0] instanceof GenerateRandomStringAction_1.GenerateRandomStringAction) {
            return CreateVariableStepDescriptor_1.VariableGenerator.PATTERN;
        }
        throw new Error('Unsupported variable generation type');
    }
    toMablscript() {
        return `${this.actions.reduce((mablscript, action) => `${mablscript}${action.toMablscript()}.`, '')}as("${this.variableName}")`;
    }
    getInputVariables() {
        return this.actions.length > 0 ? this.actions[0].getInputVariables() : [];
    }
    getOutputVariables() {
        return [this.variableName];
    }
    stepDescription() {
        switch (this.generationType) {
            case CreateVariableStepDescriptor_1.VariableGenerator.EMAIL:
                return `Generate email address for variable "${this.variableName}"`;
            case CreateVariableStepDescriptor_1.VariableGenerator.JAVASCRIPT:
                return `Execute JavaScript to create variable "${this.variableName}"`;
            case CreateVariableStepDescriptor_1.VariableGenerator.PATTERN:
                return `Generate random string for variable "${this.variableName}"`;
            case CreateVariableStepDescriptor_1.VariableGenerator.ATTRIBUTE:
                return `Extract attribute value to variable "${this.variableName}"`;
            case CreateVariableStepDescriptor_1.VariableGenerator.COOKIE_ATTRIBUTE:
                return `Extract cookie attribute to variable "${this.variableName}"`;
            case CreateVariableStepDescriptor_1.VariableGenerator.ELEMENT_COUNT:
                return `Count elements and store in variable "${this.variableName}"`;
            default:
                return `Create variable "${this.variableName}"`;
        }
    }
    static create(descriptor) {
        descriptor.id = descriptor.id ?? MablStepV2_1.MablStepV2.generateStepId();
        return new CreateVariableStep(descriptor);
    }
}
exports.CreateVariableStep = CreateVariableStep;
function isCreateVariableStep(value) {
    return (value?.getStepName &&
        value.getStepName() === CreateVariableStep.stepName &&
        !!value.generationType);
}
