import baseUtil from './base';

// // type JSON Schema
// const typeConfig = {
//   "moduleName": {
//     "api": { "type": "boolean" },
//     "api2": {
//       "name": "root",
//       "type": "object",
//       "parser": () => {},
//       "props": [
//         { "name": "age", "type": "number" }
//       ]
//     },
//     "api3": {
//       "type": "array",
//       "props": [
//         { "type": "number" }
//       ]
//     },
//   }
// };

const typeParseMap = {
  "string": "toStr",
  "number": "toNumber",
  "boolean": "toBoolean",
  "object": "toObject",
  "array": "toObject"
};

class Parser {
  constructor() {
    this._parserGen = null
    this._typeParserGen = null
    this._typeConfig = {}
  }

  /**
   * 默认parser
   */
  _parse(config, data) {
    if (!config) return data;

    const { type, props } = config;
    const parseFun = this.getTypeParser(config)
    if (!baseUtil.isFun(parseFun)) return data;

    // 类型转换
    const result = parseFun(data);
    if (!result) return result;

    // 不再深入
    if (!props || !props.length) return result;

    // 深入
    switch (type.toLowerCase()) {
      case 'object':
        props.forEach(child => {
          if (child && !baseUtil.isNull(result[child.name])) {
            result[child.name] = this._parse(child, result[child.name]);
          }
        });
        return result;
      case 'array':
        result.map(item => this._parse(props[0], item))
        return result;
      default:
        return result;
    }
  }

  /**
   * 注入类型Parse方法生成器
   */
  registTypeParserGen(fun) {
    if (baseUtil.isFun(fun)) {
      this._typeParserGen = fun
    }
  }

  /**
   * 获取类型转换方法
   * @param {any} config 
   */
  getTypeParser(config) {
    if (this._typeParserGen) {
      return this._typeParserGen(config)
    }

    // 内设parser
    const { type, parser } = config;
    if (baseUtil.isFun(parser)) return parser;

    const parseType = typeParseMap[type.toLowerCase()];
    if (parseType) return baseUtil[parseType].bind(baseUtil)

    return null;
  }

  /**
   * 注入类型配置
   */
  registTypeConfig(config) {
    if (config) {
      return Object.assign(this._typeConfig, config)
    }
  }

  /**
   * 注册Parse处理方法生成器
   */
  registParserGen(fun) {
    if (baseUtil.isFun(fun)) {
      this._parserGen = fun
    }
  }

  /**
   * 获取处理方法
   * @param {string} moduleName 
   * @param {string} api 
   */
  getParser(moduleName, api) {
    if (this._parserGen) {
      return this._parserGen(moduleName, api)
    }

    const mod = this._typeConfig[moduleName] || {};
    const config = mod[api];
    if (!config) return null;
    return (data) => this._parse(config, data);
  }

  /**
   * 数据类型转换
   * @param {string} moduleName 
   * @param {string} api 
   * @param {any} data 
   */
  parse(moduleName, api, data) {
    try {
      const parser = this.getParser(moduleName, api)
      if (!parser) return data;
      return parser(data)
    } catch (err) {
      return data;
    }
  }
}

export default new Parser()
