"use strict";

var path = require("path");
var async = require("async");
var rarity = require("rarity");
var shellExec = require('child_process').exec;
var createFakeApi = require('./helpers/fake-api.js');

var concurrencies = [1, 2];
// 5 is less than the number of tasks in our test, and 15 is greater
var tasksPerProcess = [5, 15];

concurrencies.forEach(function(concurrency) {
  tasksPerProcess.forEach(function(_tasksPerProcess) {
    describe('Hydration should be cleaned every time with concurrency = ' + concurrency + ' & tasksPerProcess = ' + _tasksPerProcess , function() {
      var fakeApi = createFakeApi();

      fakeApi.patch('/result', function(req, res, next) {
        res.send(204);
        next();
      });
      before(function() {
        fakeApi.listen(4243);
      });

      after(function() {
        fakeApi.close();
      });

      it('on normal workflow', function(done) {
        this.timeout(10000);

        var config = {
          hydrater_function: path.resolve(__dirname, './hydraters/grep-hydrater.js'),
          concurrency: concurrency,
          logger: function() {},
        };

        process.env.TASKS_PER_PROCESS = _tasksPerProcess;
        var hydrate = require('../lib/helpers/hydrater.js')(config.hydrater_function, config.concurrency, config.logger);

        var task = {
          file_path: "http://127.0.0.1:4243/afile",
          callback: "http://127.0.0.1:4243/result",
          document: {
            id: "azerty"
          },
        };

        async.waterfall([
          function getCurrentNodeProccesses(cb) {
            shellExec('ps aux | grep "[n]ode" -c', rarity.slice(2, cb));
          },
          function hydrateManyTimes(nodeProccessesAtStart, cb) {
            var hydrationCount = 0;
            async.whilst(
              function test() {
                hydrationCount += 1;
                return hydrationCount < 10;
              },
              function hydrateAndCheck(cb) {
                hydrate(task, function(err, changes) {
                  // Reuse existing process during progress
                  changes.metadata.nodeCount.should.eql(nodeProccessesAtStart);
                  shellExec('ps aux | grep "[n]ode" -c', function(err, stdout) {
                    // keep process open after use
                    parseInt(stdout).should.be.eql(nodeProccessesAtStart);
                    cb(err);
                  });
                });
              },
              cb
            );
          }
        ], done);
      });

      it('on crash', function(done) {
        this.timeout(10000);
        var config = {
          hydrater_function: path.resolve(__dirname, './hydraters/buggy-hydrater.js'),
          concurrency: concurrency,
          logger: function() {},
        };
        process.env.TASKS_PER_PROCESS = _tasksPerProcess;

        var hydrate = require('../lib/helpers/hydrater.js')(config.hydrater_function, config.concurrency, config.logger);

        var task = {
          file_path: "http://127.0.0.1:4243/afile",
          callback: "http://127.0.0.1:4243/result",
          document: {
            id: "azerty"
          },
        };

        async.waterfall([
          function getActualNodeProccesses(cb) {
            shellExec('ps aux | grep "[n]ode" -c', rarity.slice(2, cb));
          },
          function hydrateManyTimes(nodeProccessesAtStart, cb) {
            var hydrationCount = 0;
            async.whilst(
              function test() {
                hydrationCount += 1;
                return hydrationCount < 10;
              },
              function hydrateAndCheck(cb) {
                hydrate(task, function() {
                  // +0 process after work
                  shellExec('ps aux | grep "[n]ode" -c', function(err, stdout) {
                    parseInt(stdout).should.be.eql(nodeProccessesAtStart);
                    cb(err);
                  });
                });
              },
              cb
            );

          }
        ], done);
      });

      it('on error', function(done) {
        this.timeout(10000);

        var config = {
          hydrater_function: path.resolve(__dirname, '../hydraters/erroed-hydrater.js'),
          concurrency: concurrency,
          logger: function() {},
        };
        process.env.TASKS_PER_PROCESS = _tasksPerProcess;

        var hydrate = require('../lib/helpers/hydrater.js')(config.hydrater_function, config.concurrency, config.logger);

        var task = {
          file_path: "http://127.0.0.1:4243/afile",
          callback: "http://127.0.0.1:4243/result",
          document: {
            id: "azerty"
          },
        };

        async.waterfall([
          function getActualNodeProccesses(cb) {
            shellExec('ps aux | grep "[n]ode" -c', rarity.slice(2, cb));
          },
          function hydrateManyTimes(nodeProccessesAtStart, cb) {
            var hydrationCount = 0;
            async.whilst(
              function test() {
                hydrationCount += 1;
                return hydrationCount < 10;
              },
              function hydrateAndCheck(cb) {
                hydrate(task, function() {
                  // +0 process after work
                  shellExec('ps aux | grep "[n]ode" -c', function(err, stdout) {
                    parseInt(stdout).should.be.eql(nodeProccessesAtStart);
                    cb(err);
                  });
                });
              },
              cb
            );
          }
        ], done);
      });
    });
  });
});

@@ -2128,24 +2128,33 @@
 .should.eql(
+parseInt(
 nodeProccess
@@ -2155,32 +2155,33 @@
 occessesAtStart)
+)
 ;%0A              
@@ -2341,32 +2341,41 @@
 ).should.be.eql(
+parseInt(
 nodeProccessesAt
@@ -2372,32 +2372,33 @@
 occessesAtStart)
+)
 ;%0A              
@@ -3853,32 +3853,41 @@
 ).should.be.eql(
+parseInt(
 nodeProccessesAt
@@ -3884,32 +3884,33 @@
 occessesAtStart)
+)
 ;%0A              
@@ -5377,16 +5377,25 @@
 .be.eql(
+parseInt(
 nodeProc
@@ -5408,16 +5408,17 @@
 AtStart)
+)
 ;%0A      

fix should warnings