var Flow = require('./flow/flow');
var bunyan = require('bunyan');
var cache = require('./cache');
var socket = require('./socket');

module.exports = function factory (config) {

    return socket.incoming(Flow({
        module: function loadModule (name, callback) {
            try {
                var module = require(config.paths.module + '/' + 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);
            }

            callback(null, composition);
        },
        request: socket.request,
        cache: cache,
        log: bunyan,
        config: config,
        
        clientComposition: composition,
        clientMarkup: markup,
        // TODO maybe there's a better way to provide a core flow config
        _flow: {
            'C': ['clientComposition'],
            'M': ['clientMarkup']
        }
    }));
};

function markup (stream, options) {

    // TODO just use the stream and send the read file
    if (options.res && options.res.sendFile) {

        // TODO get markup from modules markup path?
        // TODO send markup snipptet from the apps public folder
        res.sendFile(config.paths.markup + '/'/*send markup file*/);
    }
}

function composition (stream, options, name) {

    name = name.toString();

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

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

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

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

    if (!composition.client) {
        return stream.end(new Error('Flow.server.composition: No client config.'));
    }

    composition.client.module = composition.module;

    stream.end(null, JSON.stringify(composition.client));
}

@@ -1061,24 +1061,25 @@
      'C': %5B'
+:
 clientCompos
@@ -1106,16 +1106,17 @@
  'M': %5B'
+:
 clientMa

test data handlers