var async = require('async');
var request = require('request');
var _ = require('lodash');
var diff = require('deep-diff').diff;
var ProgressBar = require('progress');

var compare = module.exports.compare = function compare(host1, host2, paths, callback) {
	paths.forEach(function runCase(path) {
		async.parallel({
			host1: function host1Request(cb) {
				request(host1 + path, function(e, r, b) {
					return cb(e, b);
				});
			},
			host2: function host1Request(cb) {
				request(host2 + path, function(e, r, b) {
					return cb(e, b);
				});
			}
		}, function parallelCb(error, results) {
			if (error) {
				return callback(error);
			}

			var differences = diff(results.host1, results.host2);

			return callback(undefined, differences);
		});
	});
};

var bench = module.exports.bench = function bench(hosts, paths, callback) {
	var bar = new ProgressBar('benchmarking [:bar] :percent/ (:current from :total) :etas', {
		complete: '=',
		incomplete: ' ',
		width: 20,
		total: paths.length*hosts.length
	});

	var acumulators = {};

	hosts.forEach(function createAcumulator(host, i) {
		acumulators[host] = {
			time: 0,
			calls: 0,
			errors: []
		};
	});

	async.map(paths, function runCase(path, mapCb) {


		var clients = hosts.map(function buildClient(host) {
			return function(path, cb) {

				var start = new Date();

				request(host + path, function requestCb(error, response, body) {

					var data = {
						host: host,
						path: path,
						error: error,
						body: body,
						time: Date.now() - start.getTime()
					};

					bar.tick(1);
					return cb(undefined, data);
				});
			};
		});

		clients = clients.map(function applyPathToClient(client) {
			return async.apply(client, path);
		});

		async.parallel(clients, function(error, results) {
			if (error) {
				return mapCb(error);
			}

			results.forEach(function(result, index) {
				if (result.error) {
					acumulators.errors.push({
						path: path,
						host: result.host,
						error: result.error
					});
				}
				// console.log("[%s][%s]: %s", result.host, result.path, result.time);
				acumulators[result.host].time += result.time;
				acumulators[result.host].calls++;
			});

			return mapCb();
		});

	}, function done(error) {
		return callback(error, acumulators);
	});
};
@@ -1180,15 +1180,23 @@
 .map
+Limit
 (paths,
+ 5,
  fun
@@ -1350,28 +1350,86 @@
 %09%09%09%09
-request(
+var opts = %7B%0A%09%09%09%09%09uri: 
 host
- + 
++
 path,
+%0A%09%09%09%09%09timeout: 5000%0A%09%09%09%09%7D;%0A%0A%09%09%09%09request(opts,
  fun
@@ -1974,16 +1974,29 @@
 mulators
+%5Bresult.host%5D
 .errors.
@@ -2002,16 +2002,16 @@
 .push(%7B%0A
-
 %09%09%09%09%09%09pa
@@ -2085,17 +2085,25 @@
 );%0A%09%09%09%09%7D
-%0A
+ else %7B%0A%09
 %09%09%09%09// c
@@ -2169,24 +2169,25 @@
 .time);%0A%09%09%09%09
+%09
 acumulators%5B
@@ -2220,24 +2220,25 @@
 t.time;%0A%09%09%09%09
+%09
 acumulators%5B
@@ -2259,16 +2259,22 @@
 alls++;%0A
+%09%09%09%09%7D%0A
 %09%09%09%7D);%0A%0A

fix bugs