wyvern8/akamai-nginx

View on GitHub
src/rule.js

Summary

Maintainability
A
1 hr
Test Coverage
import { Criteria } from './criteria.js';
import { Behavior } from './behavior.js';

export class Rule {

    constructor(name, criteria, criteriaMustSatisfy, behaviors, children, skipBehaviors, valueMap, depth) {
        this.name = name;
        this.criteria = criteria;
        this.criteriaMustSatisfy = criteriaMustSatisfy;
        this.behaviors = behaviors;
        this.children = children;
        this.skipBehaviors = skipBehaviors;
        this.valueMap = valueMap;
        this.depth = depth;
    }

    process() {

        let result = '\n' + this.pad(this.depth) + '-- ' + this.name + ' rule ####';
        let criteriaNames = this.criteriaNames(this.criteria) ? this.criteriaNames(this.criteria) : 'none';
        result += '\n'  + this.pad(this.depth) + '-- criteria: ' + criteriaNames;

        if (this.criteriaNamesNotRegistered(this.criteria) !== '') {
            console.error('Criteria not registered: ' + this.criteriaNamesNotRegistered(this.criteria));
        }

        if (this.anyCriteriaForRuleRegistered(this.criteria)) {
            result += '\n' + this.pad(this.depth) + 'if ' + this.processCriteria(this.criteria, this.valueMap) + ' then';
        }

        if (this.behaviors && typeof this.behaviors !== 'undefined' && this.behaviors.length > 0) {
            result += this.pad(this.depth + 1) +
                this.processBehaviors(this.behaviors, this.valueMap, this.skipBehaviors) + '\n';
        }

        let that = this;
        this.children.forEach(function (childRule) {
            let rule = new Rule(
                childRule.name,
                childRule.criteria,
                childRule.criteriaMustSatisfy,
                childRule.behaviors,
                childRule.children,
                that.skipBehaviors,
                that.valueMap,
                that.depth + 1
            );
            result += rule.process();
        });

        if (this.anyCriteriaForRuleRegistered(this.criteria)) {
            result += this.pad(this.depth) + 'end\n';
        }

        return result;
    }

    anyCriteriaForRuleRegistered(criteria) {
        if (!criteria) return false;
        let anyCriteriaRegistered = false;
        criteria.forEach((criteria) => {
            if (Criteria.isRegistered(criteria.name)) {
                anyCriteriaRegistered = true;
            }
        });
        return anyCriteriaRegistered;
    }

    criteriaNames(criteria) {
        if (!criteria) return '';
        let criteriaNameArray = [];
        criteria.forEach((criteria) => {
            criteriaNameArray.push(criteria.name);
        });
        return '(' + criteriaNameArray.join(this.criteriaJoiner()) + ')';
    }

    criteriaNamesNotRegistered(criteria) {
        if (!criteria) return '';
        let criteriaNameArray = [];
        criteria.forEach((criteria) => {
            if (!Criteria.isRegistered(criteria.name)) {
                criteriaNameArray.push(criteria.name);
            }
        });
        return criteriaNameArray.join(', ');
    }

    processCriteria(criteria, valueMap) {
        if (!criteria) return null;
        let criteriaArray = [];
        criteria.forEach((criteria) => {
            if (Criteria.isRegistered(criteria.name)) {
                let item = new Criteria(criteria.name, criteria.options, valueMap);
                criteriaArray.push(item.process());
            }
        });
        return '(' + criteriaArray.join(this.criteriaJoiner()) + ')';
    }

    processBehaviors(behaviors, valueMap, skipBehaviors) {
        if (!behaviors) return null;
        let behaviorArray = [];
        behaviors.forEach((behavior) => {
            let item = new Behavior(behavior.name, behavior.options, valueMap);

            if (skipBehaviors.includes(behavior.name)) {
                behaviorArray.push('-- ' + behavior.name + ' behavior (skipped)');

            } else {
                behaviorArray.push('-- ' + behavior.name + ' behavior');
                let behaviourResult = item.process();
                if (behaviourResult) {
                    if (Array.isArray(behaviourResult)) {
                        behaviorArray = [...behaviorArray, ...behaviourResult];
                    } else {
                        behaviorArray.push(behaviourResult);
                    }
                }
            }

        });
        return '\n' + this.pad(this.depth+1) + behaviorArray.join('\n' + this.pad(this.depth+1));
    }

    criteriaJoiner() {
        let joiner = ') and (';

        switch (this.criteriaMustSatisfy) {
        case 'all':
            joiner = ') and (';
            break;
        case 'any':
            joiner = ') or (';
            break;
        }
        return joiner;
    }

    pad(count) {
        if (!count || count <0) {count=0;}
        return (new Array(count + 1)).join('\t');
    }

}