{"size": 1784, "ext": "js", "max_stars_repo_path": "examples/CreatureIdentifier/rude.js", "max_stars_repo_name": "kaisersparpick/Rude.js", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "examples/CreatureIdentifier/rude.js", "max_issues_repo_name": "kaisersparpick/Rude.js", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "examples/CreatureIdentifier/rude.js", "max_forks_repo_name": "kaisersparpick/Rude.js", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 28.7741935484, "max_line_length": 105, "alphanum_fraction": 0.519058296}
class RudeRule {
    constructor(condition, yes, no) {
        this.condition = condition;
        this.yes = yes;
        this.no = no;
    }
}

class Rude {
    constructor(scope) {
        this.rules = {};
        this.scope = scope || undefined;
        this.log = [];
    }

    check(condition) {
        if (typeof condition !== "function") throw Error("Condition must be a function");
        let ruleName = condition.name;

        while (true) {
            let rule = this.rules[ruleName];
            if (!rule) break;
            let result = rule.condition.bound ? rule.condition.cb() : rule.condition.cb.call(this.scope);
            this.log.push({ ruleName, result });

            if (result === null) break;

            let nextRule = result ? rule.yes : rule.no;
            if (!nextRule || !nextRule.cb) break;

            ruleName = nextRule.cb.name;
        }

        return true;
    }

    static processArg(arg) {
        if (typeof arg !== "function" && typeof arg !== "undefined")
            throw Error("Invalid argument");

        if (typeof arg === "function")
            arg = { cb: arg, bound: (arg.name.startsWith("bound ")) };

        return arg;
    }

    addRule(condition, yes, no) {
        let args = [condition, yes, no].map(arg => Rude.processArg(arg));
        let key = args[0].cb.name;
        this.rules[key] = new RudeRule(args[0], args[1], args[2]);
    }

    generateLog() {
        let html = "";
        let thead = "<thead><tr><th>idx</th><th>rule name</th><th>result</th></tr></thead>";
        for (const [idx, item] of this.log.entries()) {
            html += `<tr><td>${idx}</td><td>${item.ruleName}</td><td>${item.result}</td></tr>`;
        }
        return `<table>${thead}<tbody>${html}</tbody></table>`;
    }
}
