"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

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

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));

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

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

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _get3 = _interopRequireDefault(require("@babel/runtime/helpers/get"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));

var _Fetcher = _interopRequireDefault(require("./Fetcher"));

// Always call this with `new` to make the abstraction over the inner class
// transparent to module consumers
var ExhaustivePaginatedFetcher = function ExhaustivePaginatedFetcher() {
  var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

  var _ref$SuperClass = _ref.SuperClass,
      SuperClass = _ref$SuperClass === void 0 ? _Fetcher.default : _ref$SuperClass,
      args = (0, _objectWithoutProperties2.default)(_ref, ["SuperClass"]);

  var ExhaustivePaginatedFetcher =
  /*#__PURE__*/
  function (_SuperClass) {
    (0, _inherits2.default)(ExhaustivePaginatedFetcher, _SuperClass);

    function ExhaustivePaginatedFetcher() {
      (0, _classCallCheck2.default)(this, ExhaustivePaginatedFetcher);
      return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ExhaustivePaginatedFetcher).apply(this, arguments));
    }

    (0, _createClass2.default)(ExhaustivePaginatedFetcher, [{
      key: "combinePages",
      value: function combinePages(pages) {
        return pages.reduce(function (accumulator, page) {
          return [].concat((0, _toConsumableArray2.default)(accumulator), (0, _toConsumableArray2.default)(page));
        }, []);
      }
    }, {
      key: "get",
      value: function () {
        var _get2 = (0, _asyncToGenerator2.default)(
        /*#__PURE__*/
        _regenerator.default.mark(function _callee(url) {
          var _this = this;

          var additionalParams,
              params,
              totalItems,
              itemsPerPage,
              _args = arguments;
          return _regenerator.default.wrap(function _callee$(_context) {
            while (1) {
              switch (_context.prev = _context.next) {
                case 0:
                  additionalParams = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};
                  params = {
                    method: 'GET',
                    headers: (0, _get3.default)((0, _getPrototypeOf2.default)(ExhaustivePaginatedFetcher.prototype), "callHeaders", this).call(this)
                  };
                  return _context.abrupt("return", (0, _get3.default)((0, _getPrototypeOf2.default)(ExhaustivePaginatedFetcher.prototype), "fetch", this).call(this, (0, _get3.default)((0, _getPrototypeOf2.default)(ExhaustivePaginatedFetcher.prototype), "appendQueryParams", this).call(this, url, additionalParams), params).then(function (response) {
                    // analyze properties of the first page response
                    // before getting its json body
                    totalItems = parseInt(response.headers.get('total'), 10);
                    itemsPerPage = parseInt(response.headers.get('per-page'), 10);
                    return response.json();
                  }).then(function (initial) {
                    if (totalItems > itemsPerPage) {
                      // create an array of page numbers, and use it to generate an array of
                      // get calls to the same url, but with different page numbers
                      var pageCount = Math.ceil(totalItems / itemsPerPage) - 1;
                      var pages = (0, _toConsumableArray2.default)(Array(pageCount).keys()).map(function (p) {
                        return (0, _get3.default)((0, _getPrototypeOf2.default)(ExhaustivePaginatedFetcher.prototype), "get", _this).call(_this, url, (0, _objectSpread2.default)({}, additionalParams, {
                          page: p + 2,
                          per_page: itemsPerPage
                        }));
                      });
                      return Promise.all(pages).then(function (pageResponses) {
                        return [].concat((0, _toConsumableArray2.default)(initial), (0, _toConsumableArray2.default)(_this.combinePages(pageResponses)));
                      });
                    } else {
                      return initial;
                    }
                  }));

                case 3:
                case "end":
                  return _context.stop();
              }
            }
          }, _callee, this);
        }));

        function get(_x) {
          return _get2.apply(this, arguments);
        }

        return get;
      }()
    }]);
    return ExhaustivePaginatedFetcher;
  }(SuperClass);

  return new ExhaustivePaginatedFetcher(args);
};

var _default = ExhaustivePaginatedFetcher;
exports.default = _default;