summaryrefslogtreecommitdiffstats
path: root/server/monitor-conditions/expression.js
blob: 1e70369592882d7a581a74b214d0a1ec5f26deb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
 * @readonly
 * @enum {string}
 */
const LOGICAL = {
    AND: "and",
    OR: "or",
};

/**
 * Recursively processes an array of raw condition objects and populates the given parent group with
 * corresponding ConditionExpression or ConditionExpressionGroup instances.
 * @param {Array} conditions Array of raw condition objects, where each object represents either a group or an expression.
 * @param {ConditionExpressionGroup} parentGroup The parent group to which the instantiated ConditionExpression or ConditionExpressionGroup objects will be added.
 * @returns {void}
 */
function processMonitorConditions(conditions, parentGroup) {
    conditions.forEach(condition => {
        const andOr = condition.andOr === LOGICAL.OR ? LOGICAL.OR : LOGICAL.AND;

        if (condition.type === "group") {
            const group = new ConditionExpressionGroup([], andOr);

            // Recursively process the group's children
            processMonitorConditions(condition.children, group);

            parentGroup.children.push(group);
        } else if (condition.type === "expression") {
            const expression = new ConditionExpression(condition.variable, condition.operator, condition.value, andOr);
            parentGroup.children.push(expression);
        }
    });
}

class ConditionExpressionGroup {
    /**
     * @type {ConditionExpressionGroup[]|ConditionExpression[]} Groups and/or expressions to test
     */
    children = [];

    /**
     * @type {LOGICAL} Connects group result with previous group/expression results
     */
    andOr;

    /**
     * @param {ConditionExpressionGroup[]|ConditionExpression[]} children Groups and/or expressions to test
     * @param {LOGICAL} andOr Connects group result with previous group/expression results
     */
    constructor(children = [], andOr = LOGICAL.AND) {
        this.children = children;
        this.andOr = andOr;
    }

    /**
     * @param {Monitor} monitor Monitor instance
     * @returns {ConditionExpressionGroup|null} A ConditionExpressionGroup with the Monitor's conditions
     */
    static fromMonitor(monitor) {
        const conditions = JSON.parse(monitor.conditions);
        if (conditions.length === 0) {
            return null;
        }

        const root = new ConditionExpressionGroup();
        processMonitorConditions(conditions, root);

        return root;
    }
}

class ConditionExpression {
    /**
     * @type {string} ID of variable
     */
    variable;

    /**
     * @type {string} ID of operator
     */
    operator;

    /**
     * @type {string} Value to test with the operator
     */
    value;

    /**
     * @type {LOGICAL} Connects expression result with previous group/expression results
     */
    andOr;

    /**
     * @param {string} variable ID of variable to test against
     * @param {string} operator ID of operator to test the variable with
     * @param {string} value Value to test with the operator
     * @param {LOGICAL} andOr Connects expression result with previous group/expression results
     */
    constructor(variable, operator, value, andOr = LOGICAL.AND) {
        this.variable = variable;
        this.operator = operator;
        this.value = value;
        this.andOr = andOr;
    }
}

module.exports = {
    LOGICAL,
    ConditionExpressionGroup,
    ConditionExpression,
};