import "core-js/modules/es.array.iterator";
import "core-js/modules/es.object.keys";
import "core-js/modules/es.object.to-string";
import "core-js/modules/es.string.iterator";
import "core-js/modules/es.weak-map";
import "core-js/modules/web.dom-collections.iterator";

/**
 * Utility to register plugins and common namespace for keeping reference to all plugins classes
 */
import Hooks from './pluginHooks';
import { objectEach } from './helpers/object';
import { toUpperCaseFirst } from './helpers/string';
var registeredPlugins = new WeakMap();
/**
 * Registers plugin under given name
 *
 * @param {String} pluginName
 * @param {Function} PluginClass
 */

function registerPlugin(pluginName, PluginClass) {
  var correctedPluginName = toUpperCaseFirst(pluginName);
  Hooks.getSingleton().add('construct', function () {
    if (!registeredPlugins.has(this)) {
      registeredPlugins.set(this, {});
    }

    var holder = registeredPlugins.get(this);

    if (!holder[correctedPluginName]) {
      holder[correctedPluginName] = new PluginClass(this);
    }
  });
  Hooks.getSingleton().add('afterDestroy', function () {
    if (registeredPlugins.has(this)) {
      var pluginsHolder = registeredPlugins.get(this);
      objectEach(pluginsHolder, function (plugin) {
        return plugin.destroy();
      });
      registeredPlugins.delete(this);
    }
  });
}
/**
 * @param {Object} instance
 * @param {String|Function} pluginName
 * @returns {Function} pluginClass Returns plugin instance if exists or `undefined` if not exists.
 */


function getPlugin(instance, pluginName) {
  if (typeof pluginName !== 'string') {
    throw Error('Only strings can be passed as "plugin" parameter');
  }

  var _pluginName = toUpperCaseFirst(pluginName);

  if (!registeredPlugins.has(instance) || !registeredPlugins.get(instance)[_pluginName]) {
    return void 0;
  }

  return registeredPlugins.get(instance)[_pluginName];
}
/**
 * Get all registred plugins names for concrete Handsontable instance.
 *
 * @param {Object} hotInstance
 * @returns {Array}
 */


function getRegistredPluginNames(hotInstance) {
  return registeredPlugins.has(hotInstance) ? Object.keys(registeredPlugins.get(hotInstance)) : [];
}
/**
 * Get plugin name.
 *
 * @param {Object} hotInstance
 * @param {Object} plugin
 * @returns {String|null}
 */


function getPluginName(hotInstance, plugin) {
  var pluginName = null;

  if (registeredPlugins.has(hotInstance)) {
    objectEach(registeredPlugins.get(hotInstance), function (pluginInstance, name) {
      if (pluginInstance === plugin) {
        pluginName = name;
      }
    });
  }

  return pluginName;
}

export { registerPlugin, getPlugin, getRegistredPluginNames, getPluginName };