/**
 * JsonUtil计算操作工具类
 * @author cls
 * @date 2021-01-30
 * import { JsonUtil } from "@birt/funclib/JsonUtil"
 */

export const JsonUtil = {
  /**
   * 根据关键字获取，keys联合值
   * @param {*} jo {k1:"1",k2:"a"}
   * @param {*} keys ["k1","k2"]
   * @param {*} split 可选
   * 
   * @return string "1a"
   */
  joinKeysValue(jo, keys, split) {
    split = split || "";
    let jv = "";
    keys.forEach(k => {
      jv += jo[k] + split
    })
    return jv;
  },
  /**
   * 深度克隆配置，后面覆盖前面对象
   * @param {*} sourceJson 
   * @param {*} overrideJson 
   */
  deepMerge(sourceJson, overrideJson) {
    for (var key in overrideJson) {
      // 不冲突的，直接赋值 
      if (sourceJson[key] === undefined) {
        sourceJson[key] = overrideJson[key];
        continue;
      }

      // 冲突了，如果是Object，看看有么有不冲突的属性
      // 不是Object 则以（minor）为准为主，
      if (this.isJSON(overrideJson[key]) || Array.isArray(overrideJson[key])) {
        // arguments.callee 递归调用，并且与函数名解耦 
        // arguments.callee(sourceJson[key], overrideJson[key])
        this.deepMerge(sourceJson[key], overrideJson[key]);
      } else {
        sourceJson[key] = overrideJson[key];
      }
    }
    return sourceJson;
  },
  // 克隆Json对象，包含函数
  deepClone(jo, cloneJo = {}, arykey) {
    if (Array.isArray(jo)) {
      let cloneAry = []
      jo.forEach((r, i) => {
        cloneAry.push({});
        this.deepClone(r, cloneAry[i])
      })
      return cloneAry;
    } else {
      for (let key in jo) {
        if (typeof jo[key] == "object") {
          cloneJo[key] = this.deepClone(jo[key], cloneJo[key], key);
        } else {
          cloneJo[key] = jo[key];
        }
      }
      return cloneJo;
    }
  },
  isJSON(target) {
    if (target === null) {
      return false;
    }
    return (typeof target == "object") && (target.constructor == Object);
  },
  // 获取关联字段列表，alias别名字段优先应用
  getJoinFields(sourceFields, joinFields) {
    let retuFields = {};
    let jFields = joinFields.split(",");
    jFields.forEach(f => {
      let sField = sourceFields[f];
      if (sField) {
        let alias = sField.alias || f;
        retuFields[alias] = sField;
      }
    });
    return JSON.parse(JSON.stringify(retuFields));
  },
  getMergeFields(...fields) {
    let mergeFieds = {};
    fields.forEach(f => {
      Object.assign(mergeFieds, f);
    })
    return mergeFieds;
  }
};