'use strict';

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

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

var _regenerator2 = _interopRequireDefault(_regenerator);

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 _formatJson = require('format-json');

var _formatJson2 = _interopRequireDefault(_formatJson);

var _fastJsonPatch = require('fast-json-patch');

var _fastJsonPatch2 = _interopRequireDefault(_fastJsonPatch);

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

// Class representing Feature flag functionality
var LaunchDarklyUtilsFlags = exports.LaunchDarklyUtilsFlags = function () {
    /**
     * Feature flag specific api functions attached as 'LaunchDarklyUtils.flags'
     * @constructor LaunchDarklyUtilsFlags
     * @param { Swagger } apiClient - generated launchdarkly apiClient
     * @param { Object } log - logger implementation, or 'console'
     * @param { LaunchDarklyUtils } ldUtils - primary utils class
     * @returns { LaunchDarklyUtilsFlags } feature flag api functions
     */
    function LaunchDarklyUtilsFlags(apiClient, log, ldUtils) {
        (0, _classCallCheck3.default)(this, LaunchDarklyUtilsFlags);

        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, _createClass3.default)(LaunchDarklyUtilsFlags, [{
        key: 'getFeatureFlags',


        /**
         * Get all feature flags in project
         * @param {string} projectKey - project identifier
         * @returns {Promise}
         * @fulfil {Object} feature flag list json
         * @reject {Error} object with message
         */
        value: function () {
            var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(projectKey) {
                return _regenerator2.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].getFeatureFlags({ projectKey: projectKey }).then(function (response) {
                                    return response.body;
                                }));

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

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

            function getFeatureFlags(_x) {
                return _ref.apply(this, arguments);
            }

            return getFeatureFlags;
        }()

        /**
         * Get a single feature flag by key, and optional environment
         * @param {string} projectKey - project identifier
         * @param {string} featureFlagKey - feature flag identifier
         * @param {string} environmentKeyQuery - optional environment name
         * @returns {Promise}
         * @fulfil {Object} feature flag json
         * @reject {Error} object with message
         */

    }, {
        key: 'getFeatureFlag',
        value: function () {
            var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(projectKey, featureFlagKey, environmentKeyQuery) {
                return _regenerator2.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].getFeatureFlag({
                                    projectKey: projectKey,
                                    featureFlagKey: featureFlagKey,
                                    env: environmentKeyQuery
                                }).then(function (response) {
                                    return response.body;
                                }));

                            case 4:
                                _context2.prev = 4;
                                _context2.t0 = _context2['catch'](0);
                                throw {
                                    api: 'getFeatureFlag',
                                    message: _context2.t0.message,
                                    docs: 'https://apidocs.launchdarkly.com/docs/get-feature-flag'
                                };

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

            function getFeatureFlag(_x2, _x3, _x4) {
                return _ref2.apply(this, arguments);
            }

            return getFeatureFlag;
        }()

        /**
         * Get the boolean state of a single feature flag by key, and optional environment
         * @param {string} projectKey - project identifier
         * @param {string} featureFlagKey - feature flag identifier
         * @param {string} environmentKeyQuery - environment name
         * @returns {Promise}
         * @fulfil {boolean} true/false
         * @reject {Error} object with message
         */

    }, {
        key: 'getFeatureFlagState',
        value: function () {
            var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(projectKey, featureFlagKey, environmentKeyQuery) {
                return _regenerator2.default.wrap(function _callee3$(_context3) {
                    while (1) {
                        switch (_context3.prev = _context3.next) {
                            case 0:
                                return _context3.abrupt('return', this.getFeatureFlag(projectKey, featureFlagKey, environmentKeyQuery).then(function (result) {
                                    return result.environments[environmentKeyQuery].on;
                                }));

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

            function getFeatureFlagState(_x5, _x6, _x7) {
                return _ref3.apply(this, arguments);
            }

            return getFeatureFlagState;
        }()

        /**
         * patch a feature flag by key
         * @param {string} projectKey - project identifier
         * @param {string} featureFlagKey - feature flag identifier
         * @param {Array<Object>} patchComment - array of valid json patch descriptors
         * @returns {Promise}
         * @fulfil {Object} updated feature flag json
         * @reject {Error} object with message
         */

    }, {
        key: 'updateFeatureFlag',
        value: function () {
            var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(projectKey, featureFlagKey, patchComment) {
                return _regenerator2.default.wrap(function _callee4$(_context4) {
                    while (1) {
                        switch (_context4.prev = _context4.next) {
                            case 0:
                                _context4.prev = 0;
                                return _context4.abrupt('return', this.apiClient.apis[this.API_GROUP].patchFeatureFlag({
                                    projectKey: projectKey,
                                    featureFlagKey: featureFlagKey,
                                    patchComment: patchComment
                                }).then(function (response) {
                                    return response.body;
                                }));

                            case 4:
                                _context4.prev = 4;
                                _context4.t0 = _context4['catch'](0);
                                throw {
                                    api: 'patchFeatureFlag',
                                    message: _context4.t0.message,
                                    docs: 'https://apidocs.launchdarkly.com/docs/update-feature-flag'
                                };

                            case 7:
                            case 'end':
                                return _context4.stop();
                        }
                    }
                }, _callee4, this, [[0, 4]]);
            }));

            function updateFeatureFlag(_x8, _x9, _x10) {
                return _ref4.apply(this, arguments);
            }

            return updateFeatureFlag;
        }()

        /**
         * Set the boolean state of a single feature flag by key, and environment name
         * @param {string} projectKey - project identifier
         * @param {string} featureFlagKey - feature flag identifier
         * @param {string} environmentKeyQuery - environment name
         * @param {boolean} value - true or false
         * @returns {Promise}
         * @fulfil {Object} updated feature flag json
         * @reject {Error} object with message
         */

    }, {
        key: 'toggleFeatureFlag',
        value: function () {
            var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(projectKey, featureFlagKey, environmentKeyQuery, value) {
                return _regenerator2.default.wrap(function _callee5$(_context5) {
                    while (1) {
                        switch (_context5.prev = _context5.next) {
                            case 0:
                                return _context5.abrupt('return', this.updateFeatureFlag(projectKey, featureFlagKey, [{ op: 'replace', path: '/environments/' + environmentKeyQuery + '/on', value: value }]));

                            case 1:
                            case 'end':
                                return _context5.stop();
                        }
                    }
                }, _callee5, this);
            }));

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

            return toggleFeatureFlag;
        }()

        /**
         * Migrate feature flag properties between environments in a project. this includes:
         * targets, rules, fallthrough, offVariation, prerequisites and optionally the flags on/off state.
         * @param {string} projectKey - project identifier
         * @param {string} featureFlagKey - feature flag identifier
         * @param {string} fromEnv - environment to copy flag attributes from
         * @param {string} toEnv - environment to copy flag attributes to
         * @param {boolean} includeState - optionally copy boolean state true/false
         * @returns {Promise}
         * @fulfil {Object} updated feature flag json
         * @reject {Error} object with message
         */

    }, {
        key: 'migrateFeatureFlag',
        value: function () {
            var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(projectKey, featureFlagKey, fromEnv, toEnv, includeState) {
                var _this = this;

                var that;
                return _regenerator2.default.wrap(function _callee6$(_context6) {
                    while (1) {
                        switch (_context6.prev = _context6.next) {
                            case 0:
                                that = this;
                                return _context6.abrupt('return', this.getFeatureFlag(projectKey, featureFlagKey).then(function (flag) {
                                    var patchDelta = _fastJsonPatch2.default.compare(flag.environments[toEnv], flag.environments[fromEnv]);
                                    that.log.debug('envFlagDiff for \'' + featureFlagKey + '\' ' + _formatJson2.default.plain(patchDelta));
                                    return patchDelta;
                                }).then(function (patchDelta) {
                                    var patchComment = [];
                                    patchDelta.forEach(function (patch) {
                                        if (patch.path.startsWith('/targets') || patch.path.startsWith('/rules') || patch.path.startsWith('/fallthrough') || patch.path.startsWith('/offVariation') || patch.path.startsWith('/prerequisites') || includeState && patch.path.startsWith('/on')) {
                                            // add target env obj path and push
                                            patch.path = '/environments/' + toEnv + patch.path;
                                            patchComment.push(patch);
                                        }
                                    });

                                    that.log.debug('patchComment for \'' + featureFlagKey + '\' in ' + toEnv + ' : ' + _formatJson2.default.plain(patchComment));
                                    return _this.updateFeatureFlag(projectKey, featureFlagKey, patchComment);
                                }));

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

            function migrateFeatureFlag(_x15, _x16, _x17, _x18, _x19) {
                return _ref6.apply(this, arguments);
            }

            return migrateFeatureFlag;
        }()
    }, {
        key: 'API_GROUP',
        get: function get() {
            return 'Feature flags';
        }
    }]);
    return LaunchDarklyUtilsFlags;
}();