text: /**
   * @fileOverview 模块安装插件
   * @name install.js
   * @author kiba.x.zhao <kiba.rain@qq.com>
   * @license MIT
   */
  'use strict';
  
  
  /**
   * @module
   */
  const assert = require('assert');
  const { PACKAGE_NAME } = require('../lib/constants');
  const { Engine, EngineModule } = require('../lib/engine'); // eslint-disable-line no-unused-vars
  const { createDefineFunction, createExtractFunction } = require('./utils');
  
  
  const ENGINE = Symbol('ENGINE');
  
  const MODULE_SCOPE = Symbol('MODULE_SCOPE');
  const MODULE_KEY = `${PACKAGE_NAME}:plugins:InstallPlugin`;
  exports.MODULE_KEY = MODULE_KEY;
  const debug = require('debug')(MODULE_KEY);
  const getMetadataQueue = createExtractFunction('extractModule', { scope: MODULE_SCOPE });
  
  class InstallPlugin {
  
    /**
     * 模块安装插件构造函数
     * @see {@link module:lib/engine~Engine} 引擎类
     * @class
     * @param {Engine} engine 引擎实例
     */
    constructor(engine) {
  
      debug('constructor %s', engine);
  
      assert(
        engine instanceof Engine,
        `[${MODULE_KEY}] constructor Error: wrong engine`
      );
  
      this[ENGINE] = engine;
    }
  
    /**
     *检查是否为匹配模块
     * @see {@link module:lib/engine~EngineModule} 引擎模块类型
     * @param {EngineModule} module 检查的模块
     * @return {boolean} true:匹配/false:不匹配
     */
    match(module) {
  
      debug('match %s', module);
  
      const metadataQueue = getMetadataQueue(module);
      return metadataQueue.length > 0;
    }
  
    /**
     *使用模块方法
     * @see {@link module:lib/engine~EngineModule} 引擎模块类型
     * @see {@link module:lib/engine~EngineInstallOpts} 引擎模块安装可选参数
     * @param {EngineModule} module 使用的模块
     * @param {EngineInstallOpts} opts 安装可选参数
     */
    async use(module, opts) {
  
      debug('use %s %s', module, opts);
  
      const metadataQueue = getMetadataQueue(module);
  
      const engine = this[ENGINE];
      const promises = [];
      for (const metadata of metadataQueue) {
        const promise = engine.install(metadata, opts);
        promises.push(promise);
      }
  
      await Promise.all(promises);
    }
  
  }
  
  exports.InstallPlugin = InstallPlugin;
  
  /**
   * @see {@link module:lib/engine~EngineModule} 引擎模块类型
   * @type {function(EngineModule,EngineModule):EngineModule}
   */
  const _defineModule = createDefineFunction('defineModule', { scope: MODULE_SCOPE });
  
  /**
   * 定义模块
   * @see {@link module:lib/engine~EngineModule} 引擎模块类型
   * @param {EngineModule} target 引擎模块对象
   * @param {...EngineModule} modules 引擎模块
   * @return {EngineModule} 引擎模块对象
   */
  function defineModule(target, ...modules) {
  
    debug('defineModule: %s, %s', target, modules);
  
    assert(
      modules.length > 0,
      `[${MODULE_KEY}] defineModule Error:  modules is empty`
    );
  
    return _defineModule(target, ...modules);
  }
  
  exports.defineModule = defineModule;
  