"use strict";

var _regenerator = require("babel-runtime/regenerator");

var _regenerator2 = _interopRequireDefault(_regenerator);

var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require("babel-runtime/helpers/createClass");

var _createClass3 = _interopRequireDefault(_createClass2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var invok = require("invok");
var Promise = require("ipromise");

var Filter = function () {
  function Filter(handler) {
    (0, _classCallCheck3.default)(this, Filter);

    this.handler = handler;
    this.isGeneratorFunction = Object.prototype.toString.call(handler) === "[object GeneratorFunction]";
  }

  (0, _createClass3.default)(Filter, [{
    key: "run",
    value: function run(message, next) {
      if (this.isGeneratorFunction) {
        return invok(this.handler, this, [message, next]);
      } else {
        var p = new Promise();
        this.handler(message, function () {
          next().linkTo(p);
        });
        return p;
      }
    }
  }]);
  return Filter;
}();

function resolveFilterChain(message, filterChain) {
  var currentIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;

  return filterChain[currentIndex].run(message, function () {
    return currentIndex + 1 < filterChain.length ? resolveFilterChain(message, filterChain, currentIndex + 1) : Promise.resolve();
  });
}
Filter.resolveFilterChain = resolveFilterChain;
var filterChain = [];
filterChain.push(new Filter(function (message, next) {
  message.from = 1;
  message.to = 2;
  next();
}));
filterChain.push(new Filter( /*#__PURE__*/_regenerator2.default.mark(function _callee(message, next) {
  return _regenerator2.default.wrap(function _callee$(_context) {
    while (1) {
      switch (_context.prev = _context.next) {
        case 0:
          message.data = 3;
          _context.next = 3;
          return next;

        case 3:
        case "end":
          return _context.stop();
      }
    }
  }, _callee, this);
})));
function delay(time) {
  var p = new Promise();
  setTimeout(function () {
    return p.resolve();
  }, time);
  return p;
}
filterChain.push(new Filter( /*#__PURE__*/_regenerator2.default.mark(function _callee2(message, next) {
  return _regenerator2.default.wrap(function _callee2$(_context2) {
    while (1) {
      switch (_context2.prev = _context2.next) {
        case 0:
          _context2.next = 2;
          return delay(3000);

        case 2:
          message.data = 5;
          _context2.next = 5;
          return next;

        case 5:
        case "end":
          return _context2.stop();
      }
    }
  }, _callee2, this);
})));
filterChain.push(new Filter(function (message, next) {
  setTimeout(function () {
    next();
  }, 1000);
}));
Filter.resolveFilterChain({}, filterChain).then(function (data) {
  console.log(2, data);
}, function (err) {
  console.log(err);
});