/**
 * @typedef {import('./types.d.ts').PluginDefinition} PluginDefinition
 */

/**
 * Provides a way to load "plugins" as provided by the user.
 *
 * Currently supports:
 *
 * - Root hooks
 * - Global fixtures (setup/teardown)
 * @private
 * @module plugin
 */

'use strict';

const debug = require('debug')('mocha:plugin-loader');
const {
  createInvalidPluginDefinitionError,
  createInvalidPluginImplementationError
} = require('./errors');
const {castArray} = require('./utils');

/**
 * @typedef {import('./types.d.ts').PluginLoaderOptions} PluginLoaderOptions
 */

/**
 * Built-in plugin definitions.
 */
const MochaPlugins = [
  /**
   * Root hook plugin definition
   * @type {PluginDefinition}
   */
  {
    exportName: 'mochaHooks',
    optionName: 'rootHooks',
    validate(value) {
      if (
        Array.isArray(value) ||
        (typeof value !== 'function' && typeof value !== 'object')
      ) {
        throw createInvalidPluginImplementationError(
          `mochaHooks must be an object or a function returning (or fulfilling with) an object`
        );
      }
    },
    async finalize(rootHooks) {
      if (rootHooks.length) {
        const rootHookObjects = await Promise.all(
          rootHooks.map(async hook =>
            typeof hook === 'function' ? hook() : hook
          )
        );

        return rootHookObjects.reduce(
          (acc, hook) => {
            hook = {
              beforeAll: [],
              beforeEach: [],
              afterAll: [],
              afterEach: [],
              ...hook
            };
            return {
              beforeAll: [...acc.beforeAll, ...castArray(hook.beforeAll)],
              beforeEach: [...acc.beforeEach, ...castArray(hook.beforeEach)],
              afterAll: [...acc.afterAll, ...castArray(hook.afterAll)],
              afterEach: [...acc.afterEach, ...castArray(hook.afterEach)]
            };
          },
          {beforeAll: [], beforeEach: [], afterAll: [], afterEach: []}
        );
      }
    }
  },
  /**
   * Global setup fixture plugin definition
   * @type {PluginDefinition}
   */
  {
    exportName: 'mochaGlobalSetup',
    optionName: 'globalSetup',
    validate(value) {
      let isValid = true;
      if (Array.isArray(value)) {
        if (value.some(item => typeof item !== 'function')) {
          isValid = false;
        }
      } else if (typeof value !== 'function') {
        isValid = false;
      }
      if (!isValid) {
        throw createInvalidPluginImplementationError(
          `mochaGlobalSetup must be a function or an array of functions`,
          {pluginDef: this, pluginImpl: value}
        );
      }
    }
  },
  /**
   * Global teardown fixture plugin definition
   * @type {PluginDefinition}
   */
  {
    exportName: 'mochaGlobalTeardown',
    optionName: 'globalTeardown',
    validate(value) {
      let isValid = true;
      if (Array.isArray(value)) {
        if (value.some(item => typeof item !== 'function')) {
          isValid = false;
        }
      } else if (typeof value !== 'function') {
        isValid = false;
      }
      if (!isValid) {
        throw createInvalidPluginImplementationError(
          `mochaGlobalTeardown must be a function or an array of functions`,
          {pluginDef: this, pluginImpl: value}
        );
      }
    }
  }
];

/**
 * Contains a registry of [plugin definitions]{@link PluginDefinition} and discovers plugin implementations in user-supplied code.
 *
 * - [load()]{@link #load} should be called for all required modules
 * - The result of [finalize()]{@link #finalize} should be merged into the options for the [Mocha]{@link Mocha} constructor.
 * @private
 */
class PluginLoader {
  /**
   * Initializes plugin names, plugin map, etc.
   * @param {PluginLoaderOptions} [opts] - Options
   */
  constructor({pluginDefs = MochaPlugins, ignore = []} = {}) {
    /**
     * Map of registered plugin defs
     * @type {Map<string,PluginDefinition>}
     */
    this.registered = new Map();

    /**
     * Cache of known `optionName` values for checking conflicts
     * @type {Set<string>}
     */
    this.knownOptionNames = new Set();

    /**
     * Cache of known `exportName` values for checking conflicts
     * @type {Set<string>}
     */
    this.knownExportNames = new Set();

    /**
     * Map of user-supplied plugin implementations
     * @type {Map<string,Array<*>>}
     */
    this.loaded = new Map();

    /**
     * Set of ignored plugins by export name
     * @type {Set<string>}
     */
    this.ignoredExportNames = new Set(castArray(ignore));

    castArray(pluginDefs).forEach(pluginDef => {
      this.register(pluginDef);
    });

    debug(
      'registered %d plugin defs (%d ignored)',
      this.registered.size,
      this.ignoredExportNames.size
    );
  }

  /**
   * Register a plugin
   * @param {PluginDefinition} pluginDef - Plugin definition
   */
  register(pluginDef) {
    if (!pluginDef || typeof pluginDef !== 'object') {
      throw createInvalidPluginDefinitionError(
        'pluginDef is non-object or falsy',
        pluginDef
      );
    }
    if (!pluginDef.exportName) {
      throw createInvalidPluginDefinitionError(
        `exportName is expected to be a non-empty string`,
        pluginDef
      );
    }
    let {exportName} = pluginDef;
    if (this.ignoredExportNames.has(exportName)) {
      debug(
        'refusing to register ignored plugin with export name "%s"',
        exportName
      );
      return;
    }
    exportName = String(exportName);
    pluginDef.optionName = String(pluginDef.optionName || exportName);
    if (this.knownExportNames.has(exportName)) {
      throw createInvalidPluginDefinitionError(
        `Plugin definition conflict: ${exportName}; exportName must be unique`,
        pluginDef
      );
    }
    this.loaded.set(exportName, []);
    this.registered.set(exportName, pluginDef);
    this.knownExportNames.add(exportName);
    this.knownOptionNames.add(pluginDef.optionName);
    debug('registered plugin def "%s"', exportName);
  }

  /**
   * Inspects a module's exports for known plugins and keeps them in memory.
   *
   * @param {*} requiredModule - The exports of a module loaded via `--require`
   * @returns {boolean} If one or more plugins was found, return `true`.
   */
  load(requiredModule) {
    // we should explicitly NOT fail if other stuff is exported.
    // we only care about the plugins we know about.
    if (requiredModule && typeof requiredModule === 'object') {
      return Array.from(this.knownExportNames).reduce(
        (pluginImplFound, pluginName) => {
          const pluginImpl = requiredModule[pluginName];
          if (pluginImpl) {
            const plugin = this.registered.get(pluginName);
            if (typeof plugin.validate === 'function') {
              plugin.validate(pluginImpl);
            }
            this.loaded.set(pluginName, [
              ...this.loaded.get(pluginName),
              ...castArray(pluginImpl)
            ]);
            return true;
          }
          return pluginImplFound;
        },
        false
      );
    }
    return false;
  }

  /**
   * Call the `finalize()` function of each known plugin definition on the plugins found by [load()]{@link PluginLoader#load}.
   *
   * Output suitable for passing as input into {@link Mocha} constructor.
   * @returns {Promise<object>} Object having keys corresponding to registered plugin definitions' `optionName` prop (or `exportName`, if none), and the values are the implementations as provided by a user.
   */
  async finalize() {
    const finalizedPlugins = Object.create(null);

    for await (const [exportName, pluginImpls] of this.loaded.entries()) {
      if (pluginImpls.length) {
        const plugin = this.registered.get(exportName);
        finalizedPlugins[plugin.optionName] =
          typeof plugin.finalize === 'function'
            ? await plugin.finalize(pluginImpls)
            : pluginImpls;
      }
    }

    debug('finalized plugins: %O', finalizedPlugins);
    return finalizedPlugins;
  }

  /**
   * Constructs a {@link PluginLoader}
   * @param {PluginLoaderOptions} [opts] - Plugin loader options
   */
  static create({pluginDefs = MochaPlugins, ignore = []} = {}) {
    return new PluginLoader({pluginDefs, ignore});
  }
}

module.exports = PluginLoader;
