import global from '../global';
import { sysLogger } from '../logger';
import baseUtil from '../../utils/base';
import parseUtil from '../../utils/parser';
import { callAPI, syncCallAPI } from './callManager';

export default {
  /**
   * API回溯查找，仅查找，可以是 function 或其他值
   * 回溯顺序：注入的module -> 自定义回溯方法 -> 默认返回
   */
  backTrackAPI(moduleName, api, defReturn) {
    sysLogger.debug(`upon call ${moduleName}.${api}`);
    const { modules, adapter } = global.platform || {};
    const { core } = adapter || {};

    // afterModlueTrack 平台定义的模块查找方案, 默认查找方案失败后调用
    const { afterModlueTrack: apiTrack } = core || {};

    // 通过 modules 回溯 modules.api 
    const mod = modules ? modules[moduleName] || {} : {};
    const modApi = mod[api];
    if (!baseUtil.isNull(modApi)) {
      sysLogger.debug(`got ${moduleName}.${api}:${typeof modApi} from modules`);
      return baseUtil.isFun(modApi) ? modApi.bind(mod) : modApi;
    }

    // 通过平台定义的方法回溯 modules.api 
    if (baseUtil.isFun(apiTrack)) {
      const platApi = apiTrack(moduleName, api, defReturn);
      if (!baseUtil.isNull(platApi)) {
        sysLogger.debug(`got ${moduleName}.${api}:${typeof platApi} from platfromAPITracker`);
        return platApi;
      }
    }

    // 返回默认
    return defReturn;
  },

  /**
   * 回溯调用内部封装
   * @private
   */
  _adapterCall(moduleName, api, defApi) {
    const fun = this.backTrackAPI(moduleName, api, null);
    if (baseUtil.isFun(fun)) {
      return fun;
    }

    // module查找失败，调用平台设置的通用API调用接口
    const { adapter } = global.platform || {};
    const { core } = adapter || {};
    if (core && baseUtil.isFun(core[defApi])) {
      sysLogger.debug(`use default ${defApi}`);
      return core[defApi].bind(core, moduleName, api);
    }

    // 方法未定义
    return;
  },

  /**
   * 异步调用统一处理
   */
  async _asyncCall(moduleName, api, defApi, ...params) {
    return await callAPI((moduleName, api) => {
      const fun = this._adapterCall(moduleName, api, defApi);
      if (!fun) return;

      return async (...args) => {
        const res = await fun(...args);
        return parseUtil.parse(moduleName, api, res);
      }
    }, moduleName, api, params)
  },

  /**
   * 同步调用统一处理
   */
  _syncCall(moduleName, api, defApi, ...params) {
    return syncCallAPI((moduleName, api) => {
      const fun = this._adapterCall(moduleName, api, defApi);
      if (!fun) return;

      return (...args) => {
        const res = fun(...args);

        // 不是 Promise 直接返回结果
        if (!baseUtil.isPromise(res)) {
          return parseUtil.parse(moduleName, api, res);
        }

        // 如果返回的是Promise，抹除catch
        res.catch((err) => {
          sysLogger.warn(moduleName, api, err);
        });

        // 返回void
        return;
      }
    }, moduleName, api, params)
  },

  /**
   * 事件注册，要记录并区分每次调用，确保触发回调一致
   */
  async onEvent(moduleName, api, ...params) {
    return await this._asyncCall(moduleName, api, 'onEvent', ...params);
  },

  /**
   * 事件注销，要记录并区分每次调用
   */
  async offEvent(moduleName, api, ...params) {
    return await this._asyncCall(moduleName, api, 'offEvent', ...params);
  },

  /**
   * 异步事件调用，返回 Promise，不区分每次调用
   */
  async callEvent(moduleName, api, ...params) {
    return await this._asyncCall(moduleName, api, 'callEvent', ...params);
  },

  /**
   * 同步事件调用，同步返回结果
   */
  callEventSync(moduleName, api, ...params) {
    return this._syncCall(moduleName, api, 'callEventSync', ...params);
  }
}
