(function() {
  var ChunkedExecutor, MAX_CONCURRENT_CHUNK,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  MAX_CONCURRENT_CHUNK = 20;

  module.exports = ChunkedExecutor = (function() {
    function ChunkedExecutor(pathQueue, execPathFn) {
      var p;
      this.execPathFn = execPathFn;
      this.push = __bind(this.push, this);
      this.pathQueue = (function() {
        var _i, _len, _results;
        _results = [];
        for (_i = 0, _len = pathQueue.length; _i < _len; _i++) {
          p = pathQueue[_i];
          _results.push(p);
        }
        return _results;
      })();
      this.pathCount = pathQueue.length;
      this.pathsRunning = 0;
    }

    /*
    Section: Execution
    */


    ChunkedExecutor.prototype.execute = function(doneCallback) {
      var i, _i;
      this.doneCallback = doneCallback;
      for (i = _i = 0; 0 <= MAX_CONCURRENT_CHUNK ? _i <= MAX_CONCURRENT_CHUNK : _i >= MAX_CONCURRENT_CHUNK; i = 0 <= MAX_CONCURRENT_CHUNK ? ++_i : --_i) {
        this.executeNextPathIfPossible();
      }
    };

    ChunkedExecutor.prototype.push = function(filePath) {
      this.pathCount++;
      if (this.pathsRunning < MAX_CONCURRENT_CHUNK) {
        return this.executePath(filePath);
      } else {
        return this.pathQueue.push(filePath);
      }
    };

    /*
    Section: Lifecycle Methods
    */


    ChunkedExecutor.prototype.executeNextPathIfPossible = function() {
      if (this.pathsRunning < MAX_CONCURRENT_CHUNK && this.pathQueue.length) {
        return this.executePath(this.pathQueue.shift());
      }
    };

    ChunkedExecutor.prototype.executePath = function(filePath) {
      var _this = this;
      this.pathsRunning++;
      return this.execPathFn(filePath, function() {
        _this.pathCount--;
        _this.pathsRunning--;
        return _this.checkIfFinished();
      });
    };

    ChunkedExecutor.prototype.checkIfFinished = function() {
      this.executeNextPathIfPossible();
      if (this.pathCount === 0) {
        return this.doneCallback();
      }
    };

    return ChunkedExecutor;

  })();

}).call(this);
