<commit_before>var _ = require("lodash");
var cocb = require("co-callback");
var runKRL = require("./runKRL");
var Future = require("fibers/future");
var applyInFiber = require("./applyInFiber");
var selectRulesToEvalFuture = Future.wrap(require("./selectRulesToEval"));
var noopTrue = function(){
    return true;
};

var evalRule = cocb.wrap(function*(ctx, rule){
    if(_.isFunction(rule.prelude)){
        yield runKRL(rule.prelude, ctx);
    }
    var did_fire = true;

    var cond = yield runKRL(_.get(rule, ["action_block", "condition"], noopTrue), ctx);
    var actions = _.get(rule, ["action_block", "actions"], []);
    var block_type = _.get(rule, ["action_block", "block_type"], "every");
    if(block_type === "choose"){
        actions = _.filter(actions, function(action){
            return action.label === cond;
        });
        if(_.isEmpty(actions)){
            did_fire = false;//not fired b/c nothing matched
        }
    }else if(!cond){
        did_fire = false;//not fired b/c falsey cond
    }

    if(!did_fire){
        actions = [];//don't run anything
    }

    //TODO handle more than one response type
    var mapResp = function(response){
        if((response === void 0) || (response === null)){
            return;//noop
        }
        if(response.type !== "directive"){
            return response;
        }
        return {
            type: "directive",
            options: response.options,
            name: response.name,
            meta: {
                rid: rule.rid,
                rule_name: rule.name,
                txn_id: "TODO",//TODO transactions
                eid: ctx.event.eid
            }
        };
    };
    var responses = [];
    var i;
    for(i = 0; i < actions.length; i++){
        //TODO collect errors and respond individually to the client
        //TODO try{}catch(e){}
        responses.push(mapResp(yield runKRL(actions[i].action, ctx)));
    }
    responses = _.compact(responses);

    var getPostFn = function(name){
        var fn = _.get(rule, ["postlude", name]);
        return _.isFunction(fn) ? fn : _.noop;
    };
    if(did_fire){
        ctx.emit("debug", "fired");
        yield runKRL(getPostFn("fired"), ctx);
    }else{
        ctx.emit("debug", "not fired");
        yield runKRL(getPostFn("notfired"), ctx);
    }
    yield runKRL(getPostFn("always"), ctx);

    return responses;
});

var evalRuleInFuture = Future.wrap(function(ctx, rule, callback){
    cocb.run(evalRule(ctx, rule), callback);
});

var evalRuleInFiber = function(ctx, rule){
    return evalRuleInFuture(ctx, rule).wait();
};

var runEvent = function(scheduled){
    var rule = scheduled.rule;
    var ctx = scheduled.ctx;

    ctx.emit("debug", "rule selected: " + rule.rid + " -> " + rule.name);

    ctx.rid = rule.rid;
    ctx.rule = rule;
    ctx.scope = rule.scope;
    if(_.has(ctx.rulesets, rule.rid)){
        ctx.modules_used = ctx.rulesets[rule.rid].modules_used;
    }

    var r = [];
    if(rule.foreach){
        rule.foreach(ctx, function(val, iter){
            var counter = _.size(val);
            return _.mapValues(val, function(){
                var args = _.toArray(arguments);
                counter--;
                return iter(_.assign({}, ctx, {
                    foreach_is_final: counter === 0
                }), args);
            });
        }, function(ctx){
            r.push(evalRuleInFiber(ctx, rule));
        });
    }else{
        r.push(evalRuleInFiber(ctx, rule));
    }
    return r;
};

var processEvent = function(ctx){
    ctx.emit("debug", "event being processed");

    var schedule = [];<commit_msg>runEvent no longer uses fibers<commit_after>var _ = require("lodash");
var cocb = require("co-callback");
var runKRL = require("./runKRL");
var Future = require("fibers/future");
var applyInFiber = require("./applyInFiber");
var selectRulesToEvalFuture = Future.wrap(require("./selectRulesToEval"));
var noopTrue = function(){
    return true;
};

var evalRule = cocb.wrap(function*(ctx, rule){
    if(_.isFunction(rule.prelude)){
        yield runKRL(rule.prelude, ctx);
    }
    var did_fire = true;

    var cond = yield runKRL(_.get(rule, ["action_block", "condition"], noopTrue), ctx);
    var actions = _.get(rule, ["action_block", "actions"], []);
    var block_type = _.get(rule, ["action_block", "block_type"], "every");
    if(block_type === "choose"){
        actions = _.filter(actions, function(action){
            return action.label === cond;
        });
        if(_.isEmpty(actions)){
            did_fire = false;//not fired b/c nothing matched
        }
    }else if(!cond){
        did_fire = false;//not fired b/c falsey cond
    }

    if(!did_fire){
        actions = [];//don't run anything
    }

    //TODO handle more than one response type
    var mapResp = function(response){
        if((response === void 0) || (response === null)){
            return;//noop
        }
        if(response.type !== "directive"){
            return response;
        }
        return {
            type: "directive",
            options: response.options,
            name: response.name,
            meta: {
                rid: rule.rid,
                rule_name: rule.name,
                txn_id: "TODO",//TODO transactions
                eid: ctx.event.eid
            }
        };
    };
    var responses = [];
    var i;
    for(i = 0; i < actions.length; i++){
        //TODO collect errors and respond individually to the client
        //TODO try{}catch(e){}
        responses.push(mapResp(yield runKRL(actions[i].action, ctx)));
    }
    responses = _.compact(responses);

    var getPostFn = function(name){
        var fn = _.get(rule, ["postlude", name]);
        return _.isFunction(fn) ? fn : _.noop;
    };
    if(did_fire){
        ctx.emit("debug", "fired");
        yield runKRL(getPostFn("fired"), ctx);
    }else{
        ctx.emit("debug", "not fired");
        yield runKRL(getPostFn("notfired"), ctx);
    }
    yield runKRL(getPostFn("always"), ctx);

    return responses;
});

var evalRuleInFuture = Future.wrap(function(ctx, rule, callback){
    cocb.run(evalRule(ctx, rule), callback);
});

var runEventYieldable = cocb.wrap(function*(scheduled){
    var rule = scheduled.rule;
    var ctx = scheduled.ctx;

    ctx.emit("debug", "rule selected: " + rule.rid + " -> " + rule.name);

    ctx.rid = rule.rid;
    ctx.rule = rule;
    ctx.scope = rule.scope;
    if(_.has(ctx.rulesets, rule.rid)){
        ctx.modules_used = ctx.rulesets[rule.rid].modules_used;
    }

    var r = [];
    if(rule.foreach){
        yield runKRL(rule.foreach, ctx, function(val, iter){
            var counter = _.size(val);
            return _.mapValues(val, function(){
                var args = _.toArray(arguments);
                counter--;
                return iter(_.assign({}, ctx, {
                    foreach_is_final: counter === 0
                }), args);
            });
        }, function(ctx){
            r.push(evalRuleInFuture(ctx, rule).wait());
        });
    }else{
        r.push(yield evalRule(ctx, rule));
    }
    return r;
});

var runEventFuture = Future.wrap(function(scheduled, callback){
    cocb.run(runEventYieldable(scheduled), callback);
});

var runEvent = function(scheduled){
    return runEventFuture(scheduled).wait();
};

var processEvent = function(ctx){
    ctx.emit("debug", "event being processed");

    var schedule = [];
{'fraction_non_alphanumeric': 0.15503563264757295, 'fraction_numerical': 0.0008067769261799112, 'mean_word_length': 2.257993867717915, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1160236', 'n_tokens_mistral': 2314, 'n_tokens_neox': 2243, 'n_words': 513}