/* Riot WIP, @license MIT */
import { panic, defineDefaults, MOUNT_METHOD_KEY, defineProperty, IS_PURE_SYMBOL } from '@riotjs/util';
import { PURE_COMPONENT_API } from './pure-component-api.js';
import { bindDOMNodeToComponentInstance } from './bind-dom-node-to-component-instance.js';
import { createCoreAPIMethods } from './create-core-api-methods.js';

/**
 * Create a pure component
 * @param   {Function} pureFactoryFunction - pure component factory function
 * @param   {Array} options.slots - component slots
 * @param   {Array} options.attributes - component attributes
 * @param   {Array} options.template - template factory function
 * @param   {Array} options.template - template factory function
 * @param   {any} options.props - initial component properties
 * @returns {Object} pure component object
 */

function createPureComponent(pureFactoryFunction, _ref) {
  let {
    slots,
    attributes,
    props,
    css,
    template
  } = _ref;
  if (template) panic('Pure components can not have html');
  if (css) panic('Pure components do not have css');
  const component = defineDefaults(pureFactoryFunction({
    slots,
    attributes,
    props
  }), PURE_COMPONENT_API);
  return createCoreAPIMethods(method => function () {
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    // intercept the mount calls to bind the DOM node to the pure object created
    // see also https://github.com/riot/riot/issues/2806
    if (method === MOUNT_METHOD_KEY) {
      const [element] = args; // mark this node as pure element

      defineProperty(element, IS_PURE_SYMBOL, true);
      bindDOMNodeToComponentInstance(element, component);
    }

    component[method](...args);
    return component;
  });
}

export { createPureComponent };
