
'use strict';

function createRouteFromObject(obj) {
    var code = "";
    
    if (obj.condition)
        code += "if (!(" + obj.condition + ")) return message; ";
        
    if (obj.process)
        code += obj.process;

    if (obj.transform)
        code += "return " + obj.transform + ";"
    else
        code += "return message;";
    
    var fn = new Function("message", "context", code);
    
    return createRouteFromFunction(fn);
}

function createRouteFromFunction(fn) {
    if (fn.length == 1)
        return function (message, context, cb) {
            try {
                var newmsg = fn(message);
                
                setImmediate(function () {
                    cb(null, newmsg);
                });
            }
            catch (err) {
                setImmediate(function () {
                    cb(err, null);
                });                
            }
        }
        
    if (fn.length == 2)
        return function (message, context, cb) {
            try {
                var newmsg = fn(message, context);
                
                setImmediate(function () {
                    cb(null, newmsg);
                });
            }
            catch (err) {
                setImmediate(function () {
                    cb(err, null);
                });                
            }
        }
        
    return fn;
}

function createRouteFromArray(elements) {
    var fns = [];
    
    elements.forEach(function (element) {
        fns.push(createRoute(element));
    });
    
    var l = fns.length;
    
    return function (message, context, cb) {
        var k = 0;
        
        doStep();
        
        function doStep() {
            if (k >= l) {
                setImmediate(function () { cb(null, message) });
                return;
            }
            
            context.returncb = cb;
            
            fns[k++](message, context, function (err, newmsg) {
                if (err) {
                    cb(err, null);
                    return;
                }
                
                message = newmsg;
                
                setImmediate(doStep);
            });
        };
    };
}

function createRoute(routedef) {
    if (typeof routedef == 'function')
        return createRouteFromFunction(routedef);

    if (Array.isArray(routedef))
        return createRouteFromArray(routedef);
        
    if (typeof routedef == 'object')
        return createRouteFromObject(routedef);
}

module.exports = {
    create: createRoute
};


@@ -141,31 +141,46 @@
 n + %22)) 
-return message;
+%7B cb(null, message); return; %7D
  %22;%0A    
@@ -233,16 +233,41 @@
 process;
+%0A        %0A    var retval;
 %0A%0A    if
@@ -295,56 +295,67 @@
     
-code += %22return %22 + obj.transform + %22;%22%0A    else
+retval = obj.transform%0A    else%0A        retval = %22message%22;
 %0A   
@@ -363,32 +363,97 @@
     
+%0A    
 code 
-+
 = %22
-return message;
+try %7B %22 + code + %22cb(null, %22 + retval + %22); %7D catch (err) %7B cb(err, null); %7D
 %22;%0A 
@@ -503,16 +503,22 @@
 ontext%22,
+ %22cb%22,
  code);%0A
@@ -537,35 +537,10 @@
 urn 
-createRouteFromFunction(
 fn
-)
 ;%0A%7D%0A

Refactor build route function from DSL object