'use strict';

var async = require('async');
var rarity = require('rarity');

var util = require('../util.js');
var Token = require('../models/token.js');
var Childs = require('../Childs.js');

// This worker is used to manage a list of queues, it contain one task per user calling /update
module.exports = function usersQueueGenerator(server, config, workersFile, updateFile) {
  var log = require('../index.js').log;

  return function usersQueue(job, finalCb) {
    if(server.childs[job.data.anyfetchToken]) {
      return finalCb();
    }

    async.waterfall([
      function retrieveToken(cb) {
        Token.findOne({anyfetchToken: job.data.anyfetchToken}).exec(rarity.slice(2, cb));
      },
      function createQueue(token, cb) {
        if(!token) {
          // Token was probably revoked
          finalCb();
          return cb(null);
        }

        log.info({
          user: token.accountName,
        }, "Starting tasks");

        var jsonToken = token.toJSON();
        jsonToken.anyfetchApiUrl = job.data.anyfetchApiUrl;

        var data = {
          updateFile: updateFile,
          workersFile: workersFile,
          config: config,
          token: jsonToken
        };

        var queue = server.yaqsClient.createQueue(token.accountName);

        // Start the childs, and add listeners
        var childs = new Childs(config.concurrency || 1, __dirname + '/../child-process.js', data);

        childs.on('stop', function(forced) {
          log.info({
            user: token.accountName
          }, "End of tasks");

          childs.removeAllListeners();

          if(forced) {
            return finalCb();
          }

          delete server.childs[token.anyfetchToken];
          queue.remove(function(err) {
            if(err) {
              return finalCb(err);
            }

            // Unlock the token
            token.isUpdating = false;
            token.save(finalCb);
          });
        });

        childs.on('message', function(data) {
          if(data.type === 'event') {
            if(data.event === 'failed') {
              util.logError(data.err, data.job);
            }

            data.job.queue = queue;
            server.usersQueue.emit('job.' + data.job.data.type + '.' + data.event, data.job, data.err);
          }
        });

        childs.start();

        childs.queue = queue;
        childs.anyfetchApiUrl = token.anyfetchApiUrl;

        server.childs[token.anyfetchToken] = childs;

        cb();
      }
    ], util.logError);
  };
};

@@ -69,16 +69,52 @@
 arity');
+%0Avar request = require('supertest');
 %0A%0Avar ut
@@ -881,32 +881,113 @@
 ll);%0A        %7D%0A%0A
+        var isFirst = !token.cursor;%0A        var dateStartOfTasks = new Date();%0A%0A
         log.info
@@ -1915,24 +1915,24 @@
 nalCb(err);%0A
-
             
@@ -1926,32 +1926,563 @@
 %0A            %7D%0A%0A
+            request(job.data.anyfetchApiUrl)%0A              .post('/track/provider-updated')%0A              .set('Authorization', 'Bearer : ' + job.data.anyfetchToken)%0A              .send(%7B%0A                isFirst: isFirst,%0A                timeSpendOnQueue: dateStartOfTasks - token.lastUpdate(),%0A                timeSpendOnTasks: new Date() - dateStartOfTasks,%0A                totalTimeSpend: new Date() - token.lastUpdate()%0A              %7D)%0A              .end(function(err) %7B%0A                util.logError(err);%0A              %7D);%0A%0A
             // U

Send request when providing done