import global from '../global';
import error from '../error';
import event, { EVENTS } from '../event';
import system from '../system';
import { sysLogger } from '../logger';

/**
 * core 初始化
 * 模块及平台管理
 */
export default {
  /**
   * 实例化标识
   * @private
   */
  _inited: false,

  /**
   * 实例化
   */
  init() {
    if (this._inited) return;
    sysLogger.info(`SDK inited: ${JSON.stringify(system.getConfig())}`);
    this._inited = true;
    event.emit(EVENTS.SDK_INITED, system.getConfig());
  },

  /**
   * 添加平台实例，用于支持多平台打到同一个包，但仅使用一个平台，进入就确定；
   */
  addPlatform(platform) {
    const { adapter, disabled } = platform || {};
    if (!adapter) {
      console.warn('platform adapter is undefined')
      return;
    }

    if (disabled) return;

    // 平台初始化
    global.platform = platform;

    // 初始化 error
    error.init();

    // lifecircle
    const { life } = adapter;
    if (life && life.init) life.init();
  },

  /**
   * 批量注入适配器
   */
  injectAdapters(adapters) {
    Object.keys(adapters).map(key => {
      this.injectAdapter(key, adapters[key]);
    });
  },

  /**
   * 注入单个适配器
   * @param {string} adapterName 适配器名
   * @param {Object} adapt 
   */
  injectAdapter(adapterName, adapt) {
    const { adapter } = global.platform || {};
    if (!adapter) {
      global.platform.adapter = {};
    }
    if (!adapt) return;

    const oldAdapter = adapter && adapter[adapterName];
    if (!oldAdapter) {
      global.platform.adapter[adapterName] = adapt;
      return;
    }

    global.platform.adapter[adapterName] = Object.assign(oldAdapter, adapt);
  },

  /**
   * 获取适配
   * @param {string} [adapterName] 指定适配器名称
   * @returns {Object} adapter 
   */
  getAdapter(adapterName) {
    const { adapter } = global.platform || {};
    return adapterName ? adapter[adapterName] : adapter;
  },

  /**
   * 注入模块，与老模块重名会覆盖
   * @param {Object} modules { [moduleName: string]: any };
   */
  injectModules(modules) {
    Object.keys(modules).map(key => {
      this.injectModule(key, modules[key]);
    });
  },

  /**
   * 注入单个模块
   * @param {string} moduleName 模块名
   * @param {Object} module 模块实例
   */
  injectModule(moduleName, module) {
    const { modules: oldModules } = global.platform || {};
    if (!oldModules) {
      global.platform.modules = {};
    }
    if (!module) {
      return;
    }

    const oldModule = oldModules && oldModules[moduleName];
    if (!oldModule) {
      global.platform.modules[moduleName] = module;
      return;
    }

    global.platform.modules[moduleName] = Object.assign(oldModule, module);
  },

  /**
   * 获取公共部分
   * @returns 
   */
  getCommon() {
    const { common } = global.platform || {};
    return common || {};
  }
}
