'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

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

var _regenerator2 = _interopRequireDefault(_regenerator);

var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');

var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);

var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

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

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

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

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

exports.default = withDynamoPagination;

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

function withDynamoPagination(Fetcher) {
  return function (_Fetcher) {
    (0, _inherits3.default)(_class, _Fetcher);

    function _class() {
      var _ref;

      (0, _classCallCheck3.default)(this, _class);

      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      // just pass thru the entire fetch Response object
      var _this = (0, _possibleConstructorReturn3.default)(this, (_ref = _class.__proto__ || Object.getPrototypeOf(_class)).call.apply(_ref, [this].concat(args)));

      _this.asyncResponseHandler = function (response) {
        return response;
      };
      return _this;
    }

    (0, _createClass3.default)(_class, [{
      key: 'paginatedGet',
      value: function () {
        var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(url) {
          var _this2 = this;

          var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
              actionCreator = _ref3.actionCreator;

          var lastEvaluatedHashKey, lastEvaluatedRangeKey, responses, ancillary, response, resolvedResponses;
          return _regenerator2.default.wrap(function _callee$(_context) {
            while (1) {
              switch (_context.prev = _context.next) {
                case 0:
                  lastEvaluatedHashKey = void 0, lastEvaluatedRangeKey = void 0;
                  responses = [];
                  ancillary = [];

                case 3:
                  _context.next = 5;
                  return this.get(url, {
                    lastEvaluatedHashKey: lastEvaluatedHashKey,
                    lastEvaluatedRangeKey: lastEvaluatedRangeKey
                  });

                case 5:
                  response = _context.sent;

                  responses.push(response);

                  // we handle the json parsing and dispatching asynchronously so that
                  // we can keep making network requests until pagination is exhausted
                  ancillary.push(actionCreator ? response.json().then(function (json) {
                    return _this2.dispatch(actionCreator(json));
                  }) : response.json());

                  lastEvaluatedHashKey = response.headers.get('X-Last-Evaluated-Hash-Key');
                  lastEvaluatedRangeKey = response.headers.get('X-Last-Evaluated-Range-Key');

                case 10:
                  if (lastEvaluatedHashKey && lastEvaluatedRangeKey) {
                    _context.next = 3;
                    break;
                  }

                case 11:
                  _context.next = 13;
                  return Promise.all(ancillary);

                case 13:
                  resolvedResponses = _context.sent;

                  if (!actionCreator) {
                    _context.next = 18;
                    break;
                  }

                  return _context.abrupt('return', responses);

                case 18:
                  return _context.abrupt('return', resolvedResponses.reduce(function (res, acc) {
                    return [].concat((0, _toConsumableArray3.default)(res), (0, _toConsumableArray3.default)(acc));
                  }, []));

                case 19:
                case 'end':
                  return _context.stop();
              }
            }
          }, _callee, this);
        }));

        function paginatedGet(_x) {
          return _ref2.apply(this, arguments);
        }

        return paginatedGet;
      }()
    }]);
    return _class;
  }(Fetcher);
}