/**
 * 表达式工具类
 * @author cls
 * @date 2019-05-16
 */

/**
 * 转换数据集字段访问表达式
 * @param {*} datasets 数据集实例对象枚举{ds1:{},ds2:{}}
 * @param {*} expr string 配置表达式 
 * 
 * @return string
 */
export function convertDatasetExpr(datasets, expr) {
  if (datasets && expr.indexOf("}}") > 0) {
    for (var key in datasets) {
      let re = new RegExp(key + "\\.", "g");
      expr = expr.replace(re, "datasets." + key + ".")
    }
    return eval("\"" + expr.replace("{{", "\"+").replace("}}", "+\"") + "\"")
  }
  return expr;
}

/**
    * 替换变量为注入对象变量
    * @param {*} scope 注入上下文对象 {key1:obj1,key2:obj2,...}
    * @param {*} injectId 上下文对象变量名id
    * @param {*} expr 预替换上下文对象表达式
    */
export function getScopeExpr(scope, injectId, expr) {
  for (let id in scope) {
    if (id.indexOf("$$") == -1) {
      var reg = new RegExp(id + "\\.", "g");
      expr = expr.replace(reg, injectId + "." + id + ".");
    } else {
      var reg = new RegExp("\\$\\$" + id.substring(2), "g");
      expr = expr.replace(reg, injectId + ".$" + id)
    }
  }
  return expr;
}

/**
 * 解析表达式{{变量}}值
 * @param {*} expr vue模板表达式
 * @param {*} scope 上下文变量
 */
export function execVueExpr(expr, scope) {
  if (scope) {
    expr = getScopeExpr(scope, "scope", expr);
  }
  var r = new RegExp(/\{\{((?:.|\n)+?)\}\}/g);
  var p = r.exec(expr);
  while (p) {
    var pr1 = new RegExp(
      p[0].replace(/\+/g, "\\+").
        replace(/\*/g, "\\*").
        replace(/\(/g, "\\(").
        replace(/\)/g, "\\)").
        replace(/\[/g, "\\[").
        replace(/\]/g, "\\]").
        replace(/\$/g, "\\$"),
      "g");
    let p1 = p[1];
    if (scope && p1.indexOf(".") == -1) {
      // 临时添加scope是当前记录，表达式只有字段名时应用
      p1 = "scope." + p1;
    }
    var va1 = eval(p1);
    if (va1 == undefined) {
      va1 = "";
    }
    expr = expr.replace(pr1, va1);
    p = r.exec(expr);
    // 存在匹配优先级问题，可能后面表达式先匹配
    if ((p == null) && (expr.indexOf("{{") >= 0)) {
      p = r.exec(expr);
    }
  }
  if (expr === "false") {
    return false
  } else if (expr === "undefined") {
    return;
  }
  return expr;
}

/**
 * 判断值是否为true
 * @param {} val 
 */
export function isTrueVal(val) {
  return !!(val && val != "0" && val !== "false")
}