"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isTimeConditionRelation = exports.getTemplateRelationKey = exports.getConditionRelationKey = exports.getSystemVariableRelationKey = exports.getFunctionRelationKey = exports.filterVariables = exports.getVariablePath = exports.initSysRelation = exports.initTemplateRelation = exports.initFunctionRelation = exports.initConditionRelation = exports.initVariableRelation = exports.initRelation = exports.THIS_KEY = exports.CONTEXT_KEY = exports.TIME_CONDITION_KEY = exports.FUNCTION_RELATION_KEY = exports.TEMPLATE_RELATION_KEY = exports.CONDITION_RELATION_KEY = exports.VARIABLE_REG = void 0;
exports.VARIABLE_REG = /\{\{.*?(?=(\}\}))/g;
exports.CONDITION_RELATION_KEY = '__conditions';
exports.TEMPLATE_RELATION_KEY = '__templates';
exports.FUNCTION_RELATION_KEY = '__functions';
exports.TIME_CONDITION_KEY = '__condition';
exports.CONTEXT_KEY = '__context';
exports.THIS_KEY = '$this.children';
/**
 * init relation by content
 * @param content content
 * @param relations relations (contain the relation detail)
 * @returns relation
 */
const initRelation = (content, relations) => {
    const relation = {};
    const invalids = [];
    const variableMatches = (0, exports.filterVariables)(content.schemas);
    const variablePaths = (0, exports.getVariablePath)(variableMatches);
    variablePaths.forEach((item) => {
        const [prefix, ...rest] = item.split(':');
        if (prefix !== exports.THIS_KEY) {
            let result = null;
            switch (prefix) {
                case exports.TEMPLATE_RELATION_KEY: {
                    result = (0, exports.initTemplateRelation)(rest[0]);
                    break;
                }
                case exports.CONDITION_RELATION_KEY: {
                    result = (0, exports.initConditionRelation)(rest[0]);
                    break;
                }
                case exports.FUNCTION_RELATION_KEY: {
                    result = (0, exports.initConditionRelation)(rest[0]);
                    break;
                }
                case exports.CONTEXT_KEY: {
                    result = (0, exports.initSysRelation)();
                    break;
                }
                case exports.THIS_KEY: {
                    break;
                }
                default: {
                    // general variable
                    result = (0, exports.initVariableRelation)(prefix, relations.variables);
                    break;
                }
            }
            if (result) {
                relation[item] = result;
            }
            else {
                // invalids will match from server
                invalids.push(item);
            }
        }
    });
    return { relation, invalids };
};
exports.initRelation = initRelation;
/**
 * init variable relation
 * @param variableKey
 * @param variables
 * @returns
 */
const initVariableRelation = (variableKey, variables = []) => {
    // TODO: support the variable structure
    const variable = variables.find((item) => item.name === variableKey ||
        (item.schemas || []).findIndex((variable) => variable.name === variableKey) > -1);
    if (!variable) {
        return null;
    }
    return { id: variable.id, type: 'variable' };
};
exports.initVariableRelation = initVariableRelation;
/**
 * init condition relation
 * @param conditionId
 * @returns
 */
const initConditionRelation = (conditionId) => {
    return { id: conditionId, type: 'condition' };
};
exports.initConditionRelation = initConditionRelation;
/**
 * init function relation
 * @param functionId
 * @returns
 */
const initFunctionRelation = (functionId) => {
    return { id: functionId, type: 'function' };
};
exports.initFunctionRelation = initFunctionRelation;
/**
 * init template relation
 * @param templateId
 * @returns
 */
const initTemplateRelation = (templateId) => {
    return { id: templateId, type: 'template' };
};
exports.initTemplateRelation = initTemplateRelation;
/**
 * init sys relation
 * for __context:xx:xx
 * @returns
 */
const initSysRelation = () => {
    return { type: 'sys_variable' };
};
exports.initSysRelation = initSysRelation;
/**
 * get variable used path
 * @param values ['{{AA:BB:CC}}']
 * @returns ['AA:BB:CC']
 */
const getVariablePath = (values) => {
    return values.map((item) => item.replaceAll(/\{\{/g, '')).filter((item) => !!item);
};
exports.getVariablePath = getVariablePath;
const filterVariables = (list = []) => {
    let variableMatches = [];
    list.forEach((item) => {
        const { props, directive, children = [] } = item;
        const propsStr = JSON.stringify(props);
        const directiveStr = JSON.stringify(directive);
        // match props
        const propsMatches = propsStr === null || propsStr === void 0 ? void 0 : propsStr.match(exports.VARIABLE_REG);
        if (propsMatches) {
            variableMatches = variableMatches.concat(propsMatches);
        }
        // match directive
        const dirMatches = directiveStr === null || directiveStr === void 0 ? void 0 : directiveStr.match(exports.VARIABLE_REG);
        if (dirMatches) {
            variableMatches = variableMatches.concat(dirMatches);
        }
        // match children
        if (children.length > 0) {
            variableMatches = variableMatches.concat((0, exports.filterVariables)(children));
        }
    });
    return variableMatches;
};
exports.filterVariables = filterVariables;
const getFunctionRelationKey = (contentId) => {
    return `${exports.FUNCTION_RELATION_KEY}:${contentId}`;
};
exports.getFunctionRelationKey = getFunctionRelationKey;
const getSystemVariableRelationKey = (attr) => {
    return `__context:${attr}`;
};
exports.getSystemVariableRelationKey = getSystemVariableRelationKey;
const getConditionRelationKey = (contentId) => {
    return `${exports.CONDITION_RELATION_KEY}:${contentId}`;
};
exports.getConditionRelationKey = getConditionRelationKey;
const getTemplateRelationKey = (contentId) => {
    return `${exports.TEMPLATE_RELATION_KEY}:${contentId}:schemas`;
};
exports.getTemplateRelationKey = getTemplateRelationKey;
const isTimeConditionRelation = (schemaItems) => {
    const { children = [], name = '' } = schemaItems;
    return children.length === 3 && name.startsWith(exports.TIME_CONDITION_KEY);
};
exports.isTimeConditionRelation = isTimeConditionRelation;
