var Flow = require('flow');
var socket = require('./socket');
var isJSFile = /\.js/;

module.exports = function factory (config) {
    return Flow({

        module: function loadModule (name, callback) {
            try {
                var module = require(name);
            } catch (err) {
                return callback(err);
            }

            callback(null, module);
        },

        composition: function (name, callback) {
            try {
                var composition = require(this.config.paths.composition + '/' + name + '.json');
            } catch (err) {
                return callback(err);
            }

            // server side module require path
            if (composition.module[0] === '/') {
                composition.module = this.config.paths.custom + '/' + composition.module;
            }

            callback(null, composition);
        },

        demux: socket.demux,

        // Empties all caches and reloads the modules.
        request: function () {
            socket.reset();
            CoreInst.reset();
            CoreInst.load();
        },
        config: config,
        clientComposition: composition,
        _flow: {
            'C': {"d":[':clientComposition']}
        }
    });
};

function composition (options, name, next) {

    name = name.toString();

    // handle entrypoinut
    if (name === '*') {
        var host = '';//instance = socket.upgradeReq.headers.host.split(':')[0];
        var entrypoints = this.config.entrypoints[options.session.role ? 'private' : 'public'];

        // TODO maybe entrypoints can have simple routing..
        name = entrypoints[host] || entrypoints['*']; 
    }

    if (!name) {
        return next(new Error('Flow.server.composition: No name.'));
    }

    try {
        var composition = require(this.config.paths.composition + '/' + name + '.json');
    } catch (err) {
        return next(err);
    }

    var module = composition.module;
    if (!module) {
        return next(new Error('Flow.server.composition: No module field on instance "' + name  + '".'));
    }

    // handle custom modules
    if (
        module[0] === '/' &&
        isJSFile.test(module)
    ) {
        module = composition.browser || module;

        // create client path
        (module = module.split('/')).pop();
        composition.module = module.join('/');
    } 

    next(null, JSON.stringify(composition));
}


@@ -916,16 +916,49 @@
 t.demux,
+%0A        request: socket.request,
 %0A%0A      
@@ -1016,20 +1016,18 @@
       re
-que
 s
+e
 t: funct

fix copy error