"use strict";

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

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

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

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

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

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

var _fastJsonPatch = _interopRequireDefault(require("fast-json-patch"));

var _fs = _interopRequireDefault(require("fs"));

var _path = _interopRequireDefault(require("path"));

var _globule = _interopRequireDefault(require("globule"));

var _lodash = _interopRequireDefault(require("lodash"));

// Class representing Custom role functionality
var LaunchDarklyUtilsRoles = /*#__PURE__*/function () {
  /**
   * Custom role specific api functions attached as 'LaunchDarklyUtils.roles'
   * @constructor LaunchDarklyUtilsRoles
   * @param { Swagger } apiClient - generated launchdarkly apiClient
   * @param { Object } log - logger implementation, or 'console'
   * @param { LaunchDarklyUtils } ldUtils - primary utils class
   * @returns { LaunchDarklyUtilsRoles } custom flag api functions
   */
  function LaunchDarklyUtilsRoles(apiClient, log, ldUtils) {
    (0, _classCallCheck2["default"])(this, LaunchDarklyUtilsRoles);
    this.log = log;
    this.apiClient = apiClient;
    this.ldUtils = ldUtils;

    if (!this.ldUtils) {
      throw {
        message: 'LaunchDarklyUtilsRoles constructor requires ldUtils parameter'
      };
    }
  }
  /**
   * Api group object key in LD api
   * @returns {string}
   */


  (0, _createClass2["default"])(LaunchDarklyUtilsRoles, [{
    key: "API_GROUP",
    get: function get() {
      return 'Custom roles';
    }
    /**
     * Get all custom roles in account
     * @returns {Promise}
     * @fulfil {Object} custom role list json
     * @reject {Error} object with message
     * @example ldutils getTeamMemberCustomRoles owner-sample-account@launchdarkly.com
     */

  }, {
    key: "getCustomRoles",
    value: function () {
      var _getCustomRoles = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
        return _regenerator["default"].wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                _context.prev = 0;
                return _context.abrupt("return", this.apiClient.apis[this.API_GROUP].getCustomRoles().then(function (response) {
                  return response.body;
                }));

              case 4:
                _context.prev = 4;
                _context.t0 = _context["catch"](0);
                throw {
                  api: 'getCustomRoles',
                  message: _context.t0.message,
                  docs: 'https://apidocs.launchdarkly.com/docs/list-custom-roles'
                };

              case 7:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this, [[0, 4]]);
      }));

      function getCustomRoles() {
        return _getCustomRoles.apply(this, arguments);
      }

      return getCustomRoles;
    }()
    /**
     * Get a single custom role by key
     * @param {string} customRoleKey - custom role key
     * @returns {Promise}
     * @fulfil {Object} custom role json
     * @reject {Error} object with message
     * @example ldutils getCustomRole my-role
     */

  }, {
    key: "getCustomRole",
    value: function () {
      var _getCustomRole = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(customRoleKey) {
        return _regenerator["default"].wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                _context2.prev = 0;
                return _context2.abrupt("return", this.apiClient.apis[this.API_GROUP].getCustomRole({
                  customRoleKey: customRoleKey
                }).then(function (response) {
                  return response.body;
                }));

              case 4:
                _context2.prev = 4;
                _context2.t0 = _context2["catch"](0);
                throw {
                  api: 'getCustomRole',
                  message: _context2.t0.message,
                  docs: 'https://apidocs.launchdarkly.com/docs/list-custom-roles'
                };

              case 7:
              case "end":
                return _context2.stop();
            }
          }
        }, _callee2, this, [[0, 4]]);
      }));

      function getCustomRole(_x) {
        return _getCustomRole.apply(this, arguments);
      }

      return getCustomRole;
    }()
    /**
     * Get a single role by _id
     * @param {string} customRoleId - custom role _id
     * @returns {Promise}
     * @fulfil {Object} custom role json
     * @reject {Error} object with message
     * @example ldutils getCustomRoleById <id>
     */

  }, {
    key: "getCustomRoleById",
    value: function () {
      var _getCustomRoleById = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(customRoleId) {
        var _this = this;

        return _regenerator["default"].wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                return _context3.abrupt("return", this.apiClient.apis[this.API_GROUP].getCustomRoles().then(function (roleList) {
                  var roles = _lodash["default"].filter(roleList.body.items, {
                    _id: customRoleId
                  });

                  if (roles.length !== 1) {
                    throw {
                      api: 'getCustomRoles',
                      message: "role not found for _id ".concat(customRoleId),
                      docs: 'https://apidocs.launchdarkly.com/docs/list-custom-roles'
                    };
                  }

                  return _this.getCustomRole(roles[0].key);
                }));

              case 1:
              case "end":
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));

      function getCustomRoleById(_x2) {
        return _getCustomRoleById.apply(this, arguments);
      }

      return getCustomRoleById;
    }()
    /**
     * Create a new custom role
     * @param {string} customRoleKey - custom role key
     * @param {string} customRoleName - custom role name
     * @param {string} customRolePolicyArray - array of policy objects per https://docs.launchdarkly.com/docs/custom-roles
     * @param {string} customRoleDescription - user friendly description
     * @returns {Promise}
     * @fulfil {Object} custom role json
     * @reject {Error} object with message
     * @example ldutils createCustomRole my-role "My Role" [policyArrayJson] "some description"
     */

  }, {
    key: "createCustomRole",
    value: function () {
      var _createCustomRole = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription) {
        var customRole;
        return _regenerator["default"].wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                customRole = {
                  name: customRoleName,
                  key: customRoleKey,
                  description: customRoleDescription,
                  policy: customRolePolicyArray
                };
                _context4.prev = 1;
                return _context4.abrupt("return", this.apiClient.apis[this.API_GROUP].postCustomRole({
                  customRoleBody: customRole
                }).then(function (response) {
                  return response.body;
                }));

              case 5:
                _context4.prev = 5;
                _context4.t0 = _context4["catch"](1);
                throw {
                  api: 'postCustomRole',
                  message: _context4.t0.message,
                  docs: 'https://apidocs.launchdarkly.com/docs/create-custom-role'
                };

              case 8:
              case "end":
                return _context4.stop();
            }
          }
        }, _callee4, this, [[1, 5]]);
      }));

      function createCustomRole(_x3, _x4, _x5, _x6) {
        return _createCustomRole.apply(this, arguments);
      }

      return createCustomRole;
    }()
    /**
     * Update an existing custom role
     * @param {string} customRoleKey - custom role key
     * @param {string} customRoleName - custom role name
     * @param {string} customRolePolicyArray - array of policy objects per https://docs.launchdarkly.com/docs/custom-roles
     * @param {string} customRoleDescription - user friendly description
     * @returns {Promise}
     * @fulfil {Object} updated custom role json
     * @reject {Error} object with message
     * @example ldutils updateCustomRole my-role "My Role" [policyArrayJson] "some description"
     */

  }, {
    key: "updateCustomRole",
    value: function () {
      var _updateCustomRole = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription) {
        var _this2 = this;

        var updatedCustomRole, that;
        return _regenerator["default"].wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                updatedCustomRole = {
                  name: customRoleName,
                  key: customRoleKey,
                  description: customRoleDescription,
                  policy: customRolePolicyArray
                };
                that = this;
                return _context5.abrupt("return", this.getCustomRole(customRoleKey).then(function (customRole) {
                  var patchDelta = _fastJsonPatch["default"].compare(customRole, updatedCustomRole);

                  that.log.debug("customRoleDiff for '".concat(customRoleKey, "' ").concat(JSON.stringify(patchDelta)));
                  return patchDelta;
                }).then(function (patchDelta) {
                  try {
                    return _this2.apiClient.apis[_this2.API_GROUP].patchCustomRole({
                      customRoleKey: customRoleKey,
                      patchDelta: patchDelta
                    }).then(function (response) {
                      return response.body;
                    });
                  } catch (e) {
                    throw {
                      api: 'patchCustomRole',
                      message: e.message,
                      docs: 'https://apidocs.launchdarkly.com/docs/update-custom-role'
                    };
                  }
                }));

              case 3:
              case "end":
                return _context5.stop();
            }
          }
        }, _callee5, this);
      }));

      function updateCustomRole(_x7, _x8, _x9, _x10) {
        return _updateCustomRole.apply(this, arguments);
      }

      return updateCustomRole;
    }()
    /**
     * Check for existence of role by key; update if exists, otherwise create new role
     * @param {string} customRoleKey - custom role key
     * @param {string} customRoleName - custom role name
     * @param {string} customRolePolicyArray - array of policy objects per https://docs.launchdarkly.com/docs/custom-roles
     * @param {string} customRoleDescription - user friendly description
     * @returns {Promise}
     * @fulfil {Object} updated/created custom role json
     * @reject {Error} object with message
     * @example ldutils upsertCustomRole my-role "My Role" [policyArrayJson] "some description"
     */

  }, {
    key: "upsertCustomRole",
    value: function () {
      var _upsertCustomRole = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee6(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription) {
        var _this3 = this;

        var that;
        return _regenerator["default"].wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                that = this;
                return _context6.abrupt("return", this.getCustomRole(customRoleKey).then(function () {
                  that.log.debug("Role '".concat(customRoleKey, "' Found, Updating..."));
                  return _this3.updateCustomRole(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription);
                })["catch"](function () {
                  that.log.debug("Role '".concat(customRoleKey, "' Not Found, Creating..."));
                  return _this3.createCustomRole(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription);
                }));

              case 2:
              case "end":
                return _context6.stop();
            }
          }
        }, _callee6, this);
      }));

      function upsertCustomRole(_x11, _x12, _x13, _x14) {
        return _upsertCustomRole.apply(this, arguments);
      }

      return upsertCustomRole;
    }()
    /**
     * Load a file of custom role json, and update/create roles based on this
     * @param {string} roleBulkLoadFile - path to json file (eg. exampleRoleBulkLoad.json)
     * @returns {Promise}
     * @fulfil {Object} array of updated/created role json
     * @reject {Error} object with message
     * @example ldutils bulkUpsertCustomRoles ./my-roles.json
     */

  }, {
    key: "bulkUpsertCustomRoles",
    value: function () {
      var _bulkUpsertCustomRoles = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee7(roleBulkLoadFile) {
        var filePath, roles, that;
        return _regenerator["default"].wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                filePath = _path["default"].resolve(roleBulkLoadFile);
                roles = JSON.parse(_fs["default"].readFileSync(filePath, 'utf-8'));
                that = this;
                this.log.debug("Bulk Upserting Roles from File: ".concat(filePath));
                return _context7.abrupt("return", roles.reduce(function (acc, role) {
                  return acc.then(function (results) {
                    return that.upsertCustomRole(role.key, role.name, role.policy, role.description).then(function (data) {
                      results.push(data);
                      return results;
                    });
                  });
                }, Promise.resolve([])));

              case 5:
              case "end":
                return _context7.stop();
            }
          }
        }, _callee7, this);
      }));

      function bulkUpsertCustomRoles(_x15) {
        return _bulkUpsertCustomRoles.apply(this, arguments);
      }

      return bulkUpsertCustomRoles;
    }()
    /**
     * Create/update custom roles based on a folder of multiple json files
     * @param {string} roleFolder - path to folder containing json
     * @returns {Promise}
     * @fulfil {Object} array of updated/created role json
     * @reject {Error} object with message
     * @example ldutils bulkUpsertCustomRoleFolder ./my-roles-dir-containing json
     */

  }, {
    key: "bulkUpsertCustomRoleFolder",
    value: function () {
      var _bulkUpsertCustomRoleFolder = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee9(roleFolder) {
        var folderPath, globMatch, fileArray, promises, that;
        return _regenerator["default"].wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                folderPath = _path["default"].normalize(_path["default"].resolve(roleFolder));
                globMatch = folderPath + '/*.json';
                this.log.debug("Looking for Files with Pattern '".concat(globMatch, "'"));
                fileArray = _globule["default"].find(globMatch);
                promises = [];
                that = this;
                fileArray.forEach( /*#__PURE__*/function () {
                  var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee8(file) {
                    return _regenerator["default"].wrap(function _callee8$(_context8) {
                      while (1) {
                        switch (_context8.prev = _context8.next) {
                          case 0:
                            that.log.debug("Found File '".concat(file, "'. Calling 'bulkUpsertCustomRoles'"));
                            promises.push(that.bulkUpsertCustomRoles(file));

                          case 2:
                          case "end":
                            return _context8.stop();
                        }
                      }
                    }, _callee8);
                  }));

                  return function (_x17) {
                    return _ref.apply(this, arguments);
                  };
                }()); // resolve all and flatten into single result array

                return _context9.abrupt("return", Promise.all(promises).then(function (results) {
                  return Promise.resolve([].concat.apply([], results));
                }));

              case 8:
              case "end":
                return _context9.stop();
            }
          }
        }, _callee9, this);
      }));

      function bulkUpsertCustomRoleFolder(_x16) {
        return _bulkUpsertCustomRoleFolder.apply(this, arguments);
      }

      return bulkUpsertCustomRoleFolder;
    }()
  }]);
  return LaunchDarklyUtilsRoles;
}();

exports.LaunchDarklyUtilsRoles = LaunchDarklyUtilsRoles;