/* eslint capitalized-comments: 0 */

var util = require('util');
var net = require('net');
var EventEmitter = require('events').EventEmitter;
var binary = require('binary');
var async = require('async');

var binrpc = require('./protocol.js');

/**
 * @class Server
 * @param {object} options containing a host and port attribute
 */
/** @exports server */
var Server = function (options) {
    var that = this;
    this.host = options.host;
    this.port = options.port;
    this.server = net.createServer(function (client) {
        var receiver = Buffer.alloc(0);
        var chunk = 0;
        var length;

        client.on('error', function () {
            // console.log('error ' + name + ' ' + JSON.stringify(e));
        });

        client.on('end', function () {
            // console.log('<-- ' + name + ' disconnected');
        });

        client.on('data', function (data) {
            if (chunk === 0) {
                // request header
                var vars = binary.parse(data)
                    .buffer('head', 3)
                    .word8('msgType')
                    .word32bu('msgSize')
                    .vars;
                length = vars.msgSize;
                receiver = data;
            } else {
                // append request data
                receiver = Buffer.concat([receiver, data]);
            }

            chunk += 1;

            if (receiver.length >= (length + 8)) {
                // request complete
                var request = binrpc.decodeRequest(receiver);

                receiver = Buffer.alloc(0);
                chunk = 0;

                that.handleCall(request, client);
            }
        });
    });

    this.server.listen(this.port, this.host, function () {
        // console.log('listening on ' + that.port);
    });

    this.handleCall = function (request, client) {
        if (request.method === 'system.multicall') {
            // TODO reorder WORKING datapoint
            for (var i = 0; i < request.params[0].length; i++) {
                if (request.params[0][i].params[2] === 'WORKING') {
                    request.params[0][0] = request.params[0].splice(i, 1, request.params[0][0])[0];
                }
            }
            async.mapSeries(request.params[0], that.handleSingleCall, function (err, response) {
                var buf = response ? binrpc.encodeResponse(response) : binrpc.encodeResponse('');
                client.write(buf);
            });
        } else {
            that.handleSingleCall({methodName: request.method, params: request.params}, function (err, response) {
                var buf = response ? binrpc.encodeResponse(response) : binrpc.encodeResponse('');
                client.write(buf);
            });
        }
    };

    this.handleSingleCall = function (obj, callback) {
        var method = obj.methodName;
        var params = obj.params;

        /**
         * Fires when RPC method call is received
         *
         * @event Server#[method]
         * @param {*} error
         * @param {array} params
         * @param {function} callback callback awaits params err and response
         */
        var res = that.emit(method, null, params, function (err, response) {
            callback(null, response || '');
        });

        if (!res) {
            /**
             * Fires if a RPC method call has no event handler.
             * RPC response is always an empty string.
             *
             * @event Server#NotFound
             * @param {string} method
             * @param {array} params
             */
            that.emit('NotFound', method, params);
            callback(null, '');
        }
    };
};

util.inherits(Server, EventEmitter);

module.exports = Server;

@@ -1858,1033 +1858,78 @@
 ) %7B%0A
-        if (request.method === 'system.multicall') %7B%0A            // TODO reorder WORKING datapoint%0A            for (var i = 0; i %3C request.params%5B0%5D.length; i++) %7B%0A                if (request.params%5B0%5D%5Bi%5D.params%5B2%5D === 'WORKING') %7B%0A                    request.params%5B0%5D%5B0%5D = request.params%5B0%5D.splice(i, 1, request.params%5B0%5D%5B0%5D)%5B0%5D;%0A                %7D%0A            %7D%0A            async.mapSeries(request.params%5B0%5D, that.handleSingleCall, function (err, response) %7B%0A                var buf = response ? binrpc.encodeResponse(response) : binrpc.encodeResponse('');%0A                client.write(buf);%0A            %7D);%0A        %7D else %7B%0A            that.handleSingleCall(%7BmethodName: request.method, params: request.params%7D, function (err, response) %7B%0A                var buf = response ? binrpc.encodeResponse(response) : binrpc.encodeResponse('');%0A                client.write(buf);%0A            %7D);%0A        %7D%0A    %7D;%0A%0A    this.handleSingleCall = function (obj, callback) %7B%0A        var method = obj.methodName;%0A        var params = obj
+%0A        var method = request.methodName;%0A        var params = request
 .par
@@ -2282,30 +2282,28 @@
        c
-allback(null, 
+lient.write(
 response
@@ -2687,23 +2687,27 @@
        c
-allback
+lient.write
 (null, '

remove system.multicall handling