import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _construct from "@babel/runtime/helpers/construct";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
export var EditorPresetBuilder = /*#__PURE__*/function () {
  /**
   * Returns the editor API when resolved.
   * This occurs when the preset is initially built.
   */

  function EditorPresetBuilder() {
    var _this = this;
    _classCallCheck(this, EditorPresetBuilder);
    _defineProperty(this, "safeEntry", function (plugin) {
      return Array.isArray(plugin) ? plugin : [plugin, undefined];
    });
    for (var _len = arguments.length, more = new Array(_len), _key = 0; _key < _len; _key++) {
      more[_key] = arguments[_key];
    }
    this.data = [].concat(more) || [];
    this.apiPromise = new Promise(function (r) {
      return _this.resolver = r;
    });
  }
  _createClass(EditorPresetBuilder, [{
    key: "add",
    value: function add(nextOrTuple) {
      return _construct(EditorPresetBuilder, [
      /**
       * re-cast this to NewPlugin as we've done all the type
       * safety, dependency checking, narrowing, during
       * `SafePresetCheck & VerifyPluginDependencies`
       */
      nextOrTuple].concat(_toConsumableArray(this.data)));
    }
  }, {
    key: "maybeAdd",
    value: function maybeAdd(pluginToAdd, shouldAdd) {
      var pluginOrBuilder = typeof shouldAdd === 'function' ?
      // @ts-expect-error Argument of type 'SafePresetCheck<ToAddPlugin, StackPlugins>' is not assignable to parameter of type 'ToAddPlugin'.
      shouldAdd(pluginToAdd, this) : shouldAdd;
      if (pluginOrBuilder instanceof EditorPresetBuilder) {
        return pluginOrBuilder;
      }
      var nextPluginStack = [
      /**
       * re-cast this to NewPlugin as we've done all the type
       * safety, dependency checking, narrowing, during
       * `SafePresetCheck & VerifyPluginDependencies`
       */
      pluginOrBuilder ? pluginToAdd : undefined].concat(_toConsumableArray(this.data));
      var nextEditorPresetBuilder = _construct(EditorPresetBuilder, _toConsumableArray(nextPluginStack));
      return nextEditorPresetBuilder;
    }
  }, {
    key: "has",
    value: function has(plugin) {
      return this.data.some(function (pluginPreset) {
        if (Array.isArray(pluginPreset)) {
          return pluginPreset[0] === plugin;
        }
        return pluginPreset === plugin;
      });
    }
  }, {
    key: "build",
    value: function build() {
      var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
        pluginInjectionAPI = _ref.pluginInjectionAPI,
        maybeExcludePlugins = _ref.excludePlugins;
      var excludePlugins = new Set(maybeExcludePlugins ? maybeExcludePlugins : []);
      var editorPlugins = this.processEditorPlugins({
        pluginInjectionAPI: pluginInjectionAPI,
        excludePlugins: excludePlugins
      });
      if (pluginInjectionAPI) {
        var _this$resolver;
        (_this$resolver = this.resolver) === null || _this$resolver === void 0 || _this$resolver.call(this, pluginInjectionAPI.api());
      }
      return this.removeExcludedPlugins(editorPlugins, excludePlugins);
    }
  }, {
    key: "verifyDuplicatedPlugins",
    value: function verifyDuplicatedPlugins() {
      var cache = new Set();
      this.data.filter(Boolean).forEach(function (pluginEntry) {
        var _ref2 = Array.isArray(pluginEntry) ? pluginEntry : [pluginEntry, undefined],
          _ref3 = _slicedToArray(_ref2, 2),
          pluginFn = _ref3[0],
          _ = _ref3[1];
        if (cache.has(pluginFn)) {
          throw new Error("".concat(pluginFn, " is already included!"));
        }
        cache.add(pluginFn);
      });
      return true;
    }
  }, {
    key: "processEditorPlugins",
    value: function processEditorPlugins(_ref4) {
      var _this2 = this;
      var pluginInjectionAPI = _ref4.pluginInjectionAPI,
        excludePlugins = _ref4.excludePlugins;
      this.verifyDuplicatedPlugins();
      var seen = new Set();
      var pluginsDataCopy = this.data.slice();
      var plugins = pluginsDataCopy.reverse().filter(Boolean).map(function (entry) {
        var _this2$safeEntry = _this2.safeEntry(entry),
          _this2$safeEntry2 = _slicedToArray(_this2$safeEntry, 2),
          fn = _this2$safeEntry2[0],
          config = _this2$safeEntry2[1];
        if (seen.has(fn)) {
          return null;
        }
        seen.add(fn);
        if (typeof fn !== 'function') {
          return null;
        }
        var plugin = pluginInjectionAPI ? fn({
          config: config,
          api: pluginInjectionAPI.api()
        }) : fn({
          config: config
        });
        if (plugin && excludePlugins !== null && excludePlugins !== void 0 && excludePlugins.has(plugin.name)) {
          return null;
        }
        if (!pluginInjectionAPI) {
          return plugin;
        }
        pluginInjectionAPI.onEditorPluginInitialized(plugin);
        return plugin;
      }).filter(Boolean);
      return plugins;
    }
  }, {
    key: "removeExcludedPlugins",
    value: function removeExcludedPlugins(plugins, excludes) {
      if (excludes) {
        return plugins.filter(function (plugin) {
          return !plugin || !excludes.has(plugin.name);
        });
      }
      return plugins;
    }
  }]);
  return EditorPresetBuilder;
}();