import Delegate from "./Delegate";
import ExpressionType from "../enums/ExpressionType"
import BreakWayException from "../exception/BreakWayException"
import ContinueWayException from "../exception/ContinueWayException"
import ServiceException from "../exception/ServiceException"
import ReturnWayException from "../exception/ReturnWayException"
import ExpressionException from "../exception/ExpressionException"
import JSONObject from "../instances/JSONObject"
import JSONArray from "../instances/JSONArray"

export default class Expression {
  /**
   * 节点类型
   */
  type: ExpressionType;
  /**
   * 节点值
   */
  value: any;
  /**
   * 节点对应位置
   */
  pos: number;
  /**
   * 子节点
   */
  children: (Expression | null)[];
  /**
   * 运行时对应的Delegate，Delegate中保存有实参
   */
  delegate?: Delegate;
  constructor(type: ExpressionType, pos: number, value?: any, children?: Expression[], expression?: Expression) {
    this.type = type;
    this.value = value;
    this.pos = pos;
    if (children) {
      this.children = children;
    } else if (expression) {
      this.children = [expression];
    } else {
      this.children = [];
    }
  }

  /**
   * 产生常数
   */
  public static Constant (value: any, pos: number) : Expression {
    return new Expression(ExpressionType.Constant, pos, value);
  }

  /**
   * 产生Lambda
   */
  public static Lambda (lambdaExp: Expression, pos: number) : Expression {
    return new Expression(ExpressionType.Lambda, pos, lambdaExp);
  }

  /**
   * 产生Return
   */
  public static Return (objExp: Expression, pos: number) : Expression {
    return new Expression(ExpressionType.Return, pos, null, undefined, objExp);
  }

  /**
   * 产生Break
   */
  public static Break (pos: number, objExp?: Expression) : Expression {
    return new Expression(ExpressionType.Break, pos, null, undefined, objExp);
  }

  /**
   * 产生Continue
   */
  public static Continue (pos: number, objExp?: Expression) : Expression {
    return new Expression(ExpressionType.Continue, pos, null, undefined, objExp);
  }

  /**
   * 产生Throw
   */
  public static Throw (objExp: Expression, pos: number) : Expression {
    return new Expression(ExpressionType.Throw, pos, null, undefined, objExp);
  }

  /**
   * 产生Assert
   */
  public static Assert (objExp: Expression, pos: number) : Expression {
    return new Expression(ExpressionType.Assert, pos, null, undefined, objExp);
  }

  /**
   * 产生Validate
   */
  public static Validate (objExp: Expression, pos: number) : Expression {
    return new Expression(ExpressionType.Validate, pos, null, undefined, objExp);
  }

  /**
   * 产生标识符
   */
  public static Identity (value: any, pos: number) : Expression {
    return new Expression(ExpressionType.Identity, pos, value);
  }

  /**
   * 产生Json对象，value=null, children=属性值对
   */
  public static Json (attrs: Expression[], pos: number) : Expression {
    const result = new Expression(ExpressionType.Json, pos);
    result.children.push(...attrs)
    return result;
  }

  /**
   * 逗号表达式, value=null, children=各表达式
   */
  public static Comma(children: Expression[], pos: number) : Expression {
    const result = new Expression(ExpressionType.Comma, pos);
    result.children.push(...children)
    return result;
  }

  /**
   * 函数调用
   */
  public static Call (objExp: Expression, name: string, params: Expression[], pos: number) : Expression {
    const result = new Expression(ExpressionType.Call, pos, name);
    result.children.push(objExp)
    // 把所有参数加入函数调用子中
    result.children.push(...params)
    return result;
  }

  /**
   * 产生JSON数组
   */
  public static Array (params: Expression[], pos: number) : Expression {
    return new Expression(ExpressionType.Array, pos, null, params);
  }

  /**
   * 产生参数
   */
  public static Param (objExp: Expression, value: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Param, pos, value);
    result.children.push(objExp)
    return result;
  }

  /**
   * 产生对象属性
   */
  public static Property (objExp: Expression, name: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Property, pos, name);
    result.children.push(objExp)
    return result;
  }

  /**
   * 产生属性表达式，value=属性名，children[0]=属性值
   */
  public static Attr (name: string, value: Expression, pos: number) : Expression {
    const result = new Expression(ExpressionType.Attr, pos, name);
    result.children.push(value)
    return result;
  }

  /**
   * 产生赋值语句，value=属性名/变量名，child[0]=赋值对象，child[1]=赋值内容
   */
  public static Assign (objExp: Expression | null, exp: Expression, name: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Assign, pos, name);
    result.children.push(objExp)
    result.children.push(exp)
    return result;
  }

  /**
   * 产生异常
   */
  public static Try (tryExp: Expression, catches: Expression[], pos: number, finallyExp?: Expression) : Expression {
    const tryFinally: Expression[] = [];
    tryFinally.push(tryExp)
    if (finallyExp) {
      tryFinally.push(finallyExp)
    }

    const result = new Expression(ExpressionType.Try, pos, tryFinally);
    result.children.push(...catches)
    return result;
  }

  /**
   * 产生Catch
   */
  public static Catch (className: string, varName: string, catches: Expression, pos: number) : Expression {
    const catchParameter: string[] = [];
    catchParameter.push(className)
    catchParameter.push(varName)

    const result = new Expression(ExpressionType.Catch, pos, catchParameter);
    result.children.push(catches)
    return result;
  }

  /**
   * 产生一个条件语句, test:条件，ifTrue:为真时结果，ifFalse:为假时结果
   */
  public static Condition (test: Expression, ifTrue: Expression, ifFalse: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Condition, pos, source);
    result.children.push(test)
    result.children.push(ifTrue)
    result.children.push(ifFalse)
    return result;
  }

  /**
   * 产生逻辑非语句
   */
  public static Not (exp: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Not, pos, source);
    result.children.push(exp)
    return result;
  }

  /**
   * 产生逻辑与语句
   */
  public static And (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.And, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生逻辑或语句
   */
  public static Or (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Or, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生>比较运算
   */
  public static GreaterThan (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.GreaterThan, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生>=比较运算
   */
  public static GreaterThanOrEqual (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.GreaterThanOrEqual, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生<比较运算
   */
  public static LessThan (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.LessThan, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生<=比较运算
   */
  public static LessThanOrEqual (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.LessThanOrEqual, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生==比较运算
   */
  public static Equal (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Equal, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生!=比较运算
   */
  public static NotEqual (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.NotEqual, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生+运算
   */
  public static Add (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Add, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生-运算
   */
  public static Subtract (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Subtract, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生*运算
   */
  public static Multiply (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Multiply, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生/运算
   */
  public static Divide (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Divide, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生%运算
   */
  public static Modulo (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Modulo, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生字符串连接运算
   */
  public static Concat (left: Expression, right: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.Concat, pos, source);
    result.children.push(left)
    result.children.push(right)
    return result;
  }

  /**
   * 产生数组下标
   */
  public static ArrayIndex (objExp: Expression, indexExp: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.ArrayIndex, pos, source);
    result.children.push(objExp)
    result.children.push(indexExp)
    return result;
  }

  /**
   * 产生for循环
   */
  public static For (objExp: Expression, forExp: Expression, source: string, pos: number) : Expression {
    const result = new Expression(ExpressionType.For, pos, source);
    result.children.push(objExp)
    result.children.push(forExp)
    return result;
  }

  private static isNumberC (str: string) : boolean {
    return !isNaN(Number(str));
  }

  /**
   * 覆盖toString方法，显示树状的节点信息，方便调试
   */
  public toString (level?: number) : string {
    if (!level) {
      return this.toString(0)
    } else {
      // 显示自己的类型及名称
      let result = this.space(level) + "type: " + this.type + ", value: "
        + (this.value ? this.value.toString() : "null") + "[\n]"
      // 递归显示子
      for (let i = 0; i < this.children.length; i++) {
        const child = this.children[i]
        result += (child ? child.toString(level + 1) : this.space(level + 1) + "null\n");
      }
      result += this.space(level) + "]\n"
      return result;
    }
  }

  /**
   * 执行条件处理
   */
  private condition () : any {
    // 条件
    const condExp = this.children[0]
    // 为真时表达式
    const isTrue = this.children[1]
    // 为假时表达式
    const isFalse = this.children[2]
    // 如果条件返回的不是bool值，则非空值为真，空值为假
    const obj = condExp?.invoke()
    const cond = this.getBoolean(obj)
    // 为真，返回为真的表达式，否则，返回为假的表达式
    return cond ? isTrue?.invoke() : isFalse?.invoke()
  }

  /**
   * 执行for循环
   */
  private loop () : any {
    const objExp = this.children[0]
    // 获取对象，for循环
    const obj = objExp?.invoke()

    if (obj instanceof JSONArray || obj instanceof Array) {
      // 获取循环体，循环体中row代表每一项对象, 把对象传递给循环体执行
      const body = this.children[1]
      if (obj instanceof JSONArray) {
        const array = obj as JSONArray
        for (let i = 0; i < array.length(); i++) {
          this.delegate?.put('rowIndex', i)
          this.delegate?.put('row', array.get(i))
          try {
            body?.invoke()
          } catch (e) {
            if (e instanceof BreakWayException) {
              break
            } else if (e instanceof ContinueWayException) {
              // ignore
            } else {
              throw e
            }
          }
        }
      } else {
        const array = obj as Array<any>
        for (let i = 0; i < array.length; i++) {
          this.delegate?.put('rowIndex', i)
          this.delegate?.put('row', array[i])
          try {
            body?.invoke()
          } catch (e) {
            if (e instanceof BreakWayException) {
              break
            } else if (e instanceof ContinueWayException) {
              // ignore
            } else {
              throw e
            }
          }
        }
      }
    } else if (obj instanceof JSONObject || obj instanceof Object) {
      // 获取循环体，循环体中row代表每一项对象, 把对象传递给循环体执行
      const body = this.children[1]
      if (obj instanceof JSONObject) {
        const json: JSONObject = obj as JSONObject
        for (const key of json.keySet()) {
          this.delegate?.put('rowKey', key)
          this.delegate?.put('row', json.get(key))
          try {
            body?.invoke()
          } catch (e) {
            if (e instanceof BreakWayException) {
            }
          }
        }
      } else {
        for (const key of obj) {
          this.delegate?.put('rowKey', key)
          this.delegate?.put('row', obj[key])
          try {
            body?.invoke()
          } catch (e) {
            if (e instanceof BreakWayException) {
              break
            } else if (e instanceof ContinueWayException) {
              // ignore
            } else {
              throw e
            }
          }
        }
      }
    } else {
      let start = 0;
      let length: number;
      try {
        if (objExp?.children.length == 2) {
          start = objExp?.children[0]?.invoke()
          length = objExp?.children[1]?.invoke()
        } else if (typeof obj === 'number') {
          length = obj as number
        } else {
          throw new ServiceException('for循环只接收集合对象，整数或两个整数的组合')
        }
      } catch (e) {
        throw new ServiceException('for循环只接收集合对象，整数或两个整数的组合')
      }
      // 获取循环体，循环体中row代表索引
      for (let i = start; i < length; i++) {
        const body = this.children[1]
        this.delegate?.put('row', i)
        try {
          body?.invoke()
        } catch (e) {
          if (e instanceof BreakWayException) {
            break
          } else if (e instanceof ContinueWayException) {
            // ignore
          } else {
            throw e
          }
        }
      }
    }
    return obj
  }

  /**
   * 执行集合的where过滤
   */
  private where() : any {
    const result = new JSONArray()

    const objExp = this.children[0]
    // 获取对象，where循环只针对JSONArray及list
    let array: JSONArray

    const ret = objExp?.invoke()
    if (ret instanceof JSONArray) {
      array = ret
    } else if (ret instanceof Array) {
      array = new JSONArray()
      for (let i = 0; i < ret.length; i++) {
        array.put(ret[i])
      }
    } else {
      throw new ServiceException('where循环只针对JSONArray, Array')
    }

    // 获取过滤内容，其中row代表每一项对象, 把对象传递进去执行
    const body = this.children[1]
    for (let i = 0; i < array.length(); i++) {
      const value = array.get(i)
      this.delegate?.put('row', value)
      let value2 = body?.invoke()
      if (value2 === true) {
        result.put(value)
      }
    }
    return result
  }

  /**
   * 执行集合的sum求和，求和结果为BigDecimal
   */
  private sum () : any {
    let result = 0
    const objExp = this.children[0]
    // 获取对象，sum循环只针对JSONArray
    const array = objExp?.invoke() as JSONArray
    // 获取过滤内容，其中row代表每一项对象, 把对象传递进去执行
    const body = this.children[1]
    for (let i = 0; i < array.length(); i++) {
      const value = array.get(i)
      this.delegate?.put('row', value)
      let decimal = body?.invoke().toString()
      if (decimal) {
        result = result + Number(decimal)
      }
    }
    return result
  }

  /**
   * 对函数或者取属性结果进行数值转换
   */
  private convert (source: any) : any {
    if (typeof source === 'number') {
      return source as Number
    } else {
      return source
    }
  }

  /**
   * 返回Json对象的结果，返回一个Json对象
   */
  private json () : any {
    const result: JSONObject = new JSONObject()
    for (const child of this.children) {
      const name = child?.value.toString()
      const value = child?.children[0]?.invoke()
      result.put(name, value)
    }
    return result
  }

  /**
   * 返回JSONArray结果
   */
  private array () : any {
    const result: JSONArray = new JSONArray()
    for (const child of this.children) {
      // 调用处理结果
      const value = child?.invoke()
      result.put(value)
    }
    return result
  }

  /**
   * 根据值返回boolean结果
   */
  private getBoolean (obj: any) : boolean {
    // 如果条件返回的不是bool值，则非空值为真，空值为假
    let cond : boolean
    if (typeof obj === 'boolean') {
      cond = obj as boolean
    } else {
      cond = (obj != null)
    }
    return cond
  }

  /**
   * 执行赋值过程
   */
  private assign () : any {
    // 属性值
    const right = this.children[1]
    const value = right?.invoke()
    // 获取属性
    const name = this.value
    if (this.delegate?.getLambdaOutProps().includes(name)) {
      throw new ServiceException("lambda 表达式中使用的外层参数[" + name + "]为常量，不允许显性改变")
    }
    // 要赋值的对象，空代表给变量赋值
    const left = this.children[0]
    if (left == null) {
      this.delegate?.put(name, value)
    } else {
      const obj = left.invoke()
      // 如果是JSONObject，调用JSONObject的赋值过程
      if (obj instanceof JSONObject) {
        const json : JSONObject = obj as JSONObject
        json.put(name, value)
      } else {
        try {
          obj[name] = value
          return value;
        } catch (e) {
          throw new ServiceException("属性赋值错误：" + name);
        }
      }
    }
    return value
  }

  /**
   * 获取对象属性
   */
  private property(key: string = this.value.toString()) : any {
    const objExp = this.children[0]
    // 获取对象
    const obj = objExp?.invoke();
    // 属性名
    let rObj : any;
    // 是JSONObject
    if (obj instanceof JSONObject) {
      const json = obj as JSONObject
      if (!json.has(key)) {
        return null;
      }
      rObj = json.get(key)
    } else {
      rObj = obj[key]
    }
    return this.convert(rObj)
  }

  /**
   * 获取数组元素
   */
  private arrayIndex () : any {
    const objExp = this.children[0]
    const indexExp = this.children[1]
    // 获取对象
    const obj = objExp?.invoke()
    // 如果对象为JSONArray，调用JSONArray的方法
    if (obj instanceof JSONArray) {
      const array : JSONArray = obj as JSONArray
      // 获取下标值
      const index = Number(indexExp?.invoke())
      const oRet = array.get(index)
      return this.convert(oRet)
    } else if (obj instanceof Array) {
      let list = obj as Array<any>
      // 获取下标值
      const index = Number(indexExp?.invoke())
      const oRet = list[index]
      return this.convert(oRet)
    } else {
      try {
        // 获取键
        const key = indexExp?.invoke().toString()
        return this.property(key)
      } catch (e) {
        if (!(e instanceof Error)) {
          e = new Error(e as any);
        }
        throw new ExpressionException(this.delegate?.getSource() as string, this.pos as number, e as Error)
      }
    }
  }


  /**
   * 产生多个空格
   */
  private space (n: number) : string {
    let result = ''
    for (let i = 0; i < n; i++) {
      result += ' '
    }
    return result
  }

  /**
   * 跳出业务
   */
  private returnBusiness () : any {
    const value = this.children[0]?.invoke();
    throw new ReturnWayException(value);
  }

  /**
   * 抛出业务异常
   */
  private throwException() : any {
    let result = this.children[0]?.invoke()
    if (result instanceof JSONObject) {
      const obj : JSONObject = result as JSONObject
      throw new ServiceException(obj.get('msg').toString(), obj.getInt('status'))
    } else if (result instanceof Error) {
      const e = result as Error;
      if (e instanceof ServiceException) {
        throw e;
      }
      throw new ExpressionException(this.delegate?.getSource() as string, this.pos as number, e)
    } else {
      if (result == undefined || result === '') {
        result = '未定义异常'
      }
      throw new ServiceException(result.toString(), 400)
    }
  }

  /**
   * 断言处理
   */
  private assertExp() : any {
    const expression = this.children[0]
    const result = expression?.invoke()
    if (typeof result === 'boolean') {
      const yn = result as boolean
      if (!yn) {
        throw new ServiceException("断言校验失败", 400)
      }
    } else {
      throw new ServiceException("assert仅接收boolean结果")
    }
    return true
  }

  /**
   * 参数校验
   */
  private validateParams () : any {
    const result = this.children[0]?.invoke()
    if (result instanceof JSONObject) {
      const validateJson : JSONObject = result as JSONObject
      const params = this.delegate?.get('data');
      this.validateMain('data', params, validateJson)
    } else {
      throw new ServiceException("validate仅接收json格式的对象")
    }
    return result;
  }

  /**
   * lambda
   */
  private lambda() : Delegate {
    return new Delegate(this.value as Expression, this.delegate?.getSource() as string, this.delegate?.getObjectNames());
  }

  /**
   * 参数校验实现
   */
  private validateMain (validateItemKey: string, params: JSONObject, validateJson: JSONObject) : void {
    for (const key of validateJson.keySet()) {
      const item : JSONObject = validateJson.getJSONObject(key);
      const validateMode = item.optString('mode', 'normal');
      switch (validateMode) {
        case 'normal':
          const hasParams: boolean = params.has(key) && params.opt(key);
          if (!hasParams) {
            if (item.optBoolean('required', false)){
              const message = item.optString('message', '参数校验失败，' + validateItemKey + '>>' + key + '不能为空')
              throw new ServiceException(message, 400);
            }
            if (item.has('default')){
              params.put(key, item.get('default'));
            }
          }
          // items用于对JSON参数的成员进行校验
          if (item.has('items')) {
            const itemsValidate = item.getJSONObject('items');
            this.validateMain(validateItemKey + '>>' + key, params.getJSONObject(key), itemsValidate)
          }
          break;
        case 'atLeastOne':
          const fields : JSONArray = item.getJSONArray('fields');
          let isValidate = false;
          for (let i = 0; i < fields.length(); i++) {
            const field = fields.get(i);
            const fieldName = field.toString();
            const hasParam = params.has(fieldName) && params.get(fieldName) != null;
            if (hasParam) {
              isValidate = true;
              break;
            }
          }
          if (!isValidate) {
            const message = item.optString('message', '参数校验失败:参数组' + fields + '至少有一个不能为空')
            throw new ServiceException(message, 400);
          }
          break;
      }
    }
  }

  private Param() : any {
    return this.children[0]?.invoke()
  }

  /**
   * 执行 Try-Catch-Finally 语句块
   */
  private try(): any {
    const exps: Expression[] = this.value as Expression[];
    const tryExp: Expression = exps[0];

    try {
      // 执行 try 块
      return tryExp.invoke();
    } catch (ex) {
      const e: any = ex instanceof Error ? (ex as { cause?: any }).cause : ex;

      // 执行 catch 块
      for (const exp of this.children) {
        const catchValues: string[] = exp?.value as string[];
        const typeName: string = catchValues[0];
        const varName: string = catchValues[1];

        // 找到了 catch 部分，获取异常类型
        if (this.isEqual(e, typeName)) {
          const catchExp = exp?.children as Expression[];
          // 把异常值变成变量
          this.delegate?.put(varName, e);
          return catchExp[0].invoke();
        }
      }

      // 未匹配到异常，重新抛出原异常
      throw ex;
    } finally {
      // 执行 finally 块
      if (exps.length > 1) {
        const finallyExp: Expression = exps[1];
        if (finallyExp != null) {
          finallyExp.invoke();
        }
      }
    }
  }

  /**
   * 判断异常类型是否匹配
   */
  private isEqual(exception: any, typeName: string): boolean {
    if (typeName === 'Exception' || typeName === 'Error') {
      return true;
    }
    return exception && exception.constructor.name === typeName;
  }

  /**
   * 执行
   */
  public invoke () : any {
    try {
      switch (this.type) {
        // 逻辑运算
        case ExpressionType.Or: {
          const left: Expression = this.children[0] as Expression;
          const l = this.getBoolean(left.invoke());
          if (l === true) {
            return true;
          } else {
            const right: Expression = this.children[1] as Expression;
            return this.getBoolean(right.invoke());
          }
        }
        case ExpressionType.And: {
          const left: Expression = this.children[0] as Expression;
          const right: Expression = this.children[1] as Expression;
          const l = this.getBoolean(left.invoke());
          if (l === true) {
            return this.getBoolean(right.invoke());
          } else {
            return false;
          }
        }
        case ExpressionType.Not: {
          const left: Expression = this.children[0] as Expression;
          return !this.getBoolean(left.invoke());
        }
        // 算数运算
        case ExpressionType.Add:
        case ExpressionType.Subtract:
        case ExpressionType.Multiply:
        case ExpressionType.Divide:
        case ExpressionType.Modulo: {
          return this.math();
        }
        // 字符串连接
        case ExpressionType.Concat: {
          const left: Expression = this.children[0] as Expression;
          const right: Expression = this.children[1] as Expression;
          let l = left.invoke();
          if (l == null) {
            l = 'null';
          }
          let r = right.invoke();
          if (r == null) {
            r = 'null';
          }
          return l.toString() + r.toString();
        }
        // 返回JSON
        case ExpressionType.Json: {
          return this.json();
        }
        // 返回JSONArray
        case ExpressionType.Array: {
          return this.array();
        }
        // 比较运算
        case ExpressionType.GreaterThan:
        case ExpressionType.GreaterThanOrEqual:
        case ExpressionType.LessThan:
        case ExpressionType.LessThanOrEqual: {
          const left: Expression = this.children[0] as Expression;
          const right: Expression = this.children[1] as Expression;
          const l = left.invoke();
          const r = right.invoke();
          if (l == null || r == null) {
            return false;
          }
          // 两个字符串比较
          if (typeof l === 'string' && typeof r === 'string') {
            const result = l.localeCompare(r); // 使用localeCompare来比较字符串
            return this.compare(result);
          } else {
            const dl = Number(l); // 转换成数字
            const dr = Number(r); // 转换成数字
            if (isNaN(dl) || isNaN(dr)) {
              return false; // 如果转换失败，返回 false
            }
            return this.compare(dl - dr); // 进行数字比较
          }
        }
        // 比较运算
        case ExpressionType.Equal:
        case ExpressionType.NotEqual: {
          const left: Expression = this.children[0] as Expression;
          const right: Expression = this.children[1] as Expression;
          let l: any = left.invoke();
          let r: any = right.invoke();

          // 如果 l 或 r 为 null，替换成字符串 "null"
          if (l == null) {
            l = "null";
          }
          if (r == null) {
            r = "null";
          }

          let equals: boolean;

          // 校验参考的是 JS 的 ==，即宽松相等比较
          if ((typeof l === 'number' && typeof r === 'number') ||
            ((typeof l === 'number' || typeof r === 'number') && this.isNumberC(l.toString()) && this.isNumberC(r.toString()))) {
            // 比较两个数字，使用 Number 进行转换
            equals = Number(l) === Number(r);
          } else {
            // 比较字符串
            equals = String(l) === String(r);
          }

          return this.type === ExpressionType.Equal ? equals : !equals;
        }
        // 常数
        case ExpressionType.Constant: {
          return this.value;
        }
        // 标识符，获取实参对象
        case ExpressionType.Identity: {
          // 如果参数不存在，返回空
          const name = this.value as string;
          if (!this.delegate?.containsKey(name)) {
            return null;
          }
          return this.delegate?.get(name);
        }
        // 条件语句
        case ExpressionType.Condition: {
          return this.condition();
        }
        // 获取属性值
        case ExpressionType.Property: {
          return this.property();
        }
        // 获取数组元素
        case ExpressionType.ArrayIndex: {
          return this.arrayIndex();
        }
        // 函数调用
        case ExpressionType.Call: {
          return this.call();
        }
        // For循环
        case ExpressionType.For: {
          return this.loop();
        }
        // 属性赋值
        case ExpressionType.Assign: {
          return this.assign();
        }
        // 逗号表达式
        case ExpressionType.Comma: {
          let value : any = 0;
          for (const child of this.children) {
            value = child?.invoke();
          }
          return value;
        }
        // 异常处理
        case ExpressionType.Try: {
          return this.try();
        }
        // 参数
        case ExpressionType.Param: {
          return this.Param();
        }
        // Return
        case ExpressionType.Return: {
          return this.returnBusiness();
        }
        // Throw
        case ExpressionType.Throw: {
          return this.throwException();
        }
        // Assert
        case ExpressionType.Assert: {
          return this.assertExp();
        }
        // Validate
        case ExpressionType.Validate: {
          return this.validateParams();
        }
        // Lambda
        case ExpressionType.Lambda: {
          return this.lambda();
        }
        // Break
        case ExpressionType.Break: {
          throw new BreakWayException();
        }
        // Continue
        case ExpressionType.Continue: {
          throw new ContinueWayException();
        }
        default: {
          throw new ServiceException("无效操作");
        }
      }
    } catch (ex) {
      if (ex instanceof ReturnWayException ||
        ex instanceof BreakWayException ||
        ex instanceof ContinueWayException ||
        ex instanceof ExpressionException) {
        throw ex;
      } else {
        if (!(ex instanceof Error)) {
          ex = new Error(ex as any);
        }
        throw new ExpressionException(this.delegate?.getSource() as string, this.pos as number, ex as Error);
      }
    }
  }

  private compare(result: number) : boolean {
    switch (this.type) {
      case ExpressionType.GreaterThan:
        return result > 0;
      case ExpressionType.GreaterThanOrEqual:
        return result >= 0;
      case ExpressionType.LessThan:
        return result < 0;
      case ExpressionType.LessThanOrEqual:
        return result <= 0;
      default:
        throw new ServiceException("未知类型");
    }
  }

  /**
   * 执行数学运算
   *
   * @return 运算结果
   */
  private math(): any {
    const left: Expression = this.children[0] as Expression;
    const right: Expression = this.children[1] as Expression;
    const oLeft: any = left.invoke();
    const oRight: any = right.invoke();

    // 统一将输入转换为浮点数，既支持整数也支持浮点数
    const l = Number(oLeft); // 使用 Number 统一转换
    const r = Number(oRight); // 使用 Number 统一转换

    if (isNaN(l) || isNaN(r)) {
      throw new ServiceException("无效的数字");
    }

    switch (this.type) {
      case ExpressionType.Add:
        return l + r;
      case ExpressionType.Subtract:
        return l - r;
      case ExpressionType.Multiply:
        return l * r;
      case ExpressionType.Divide:
        return r !== 0 ? l / r : NaN; // 防止除以0
      case ExpressionType.Modulo:
        return l % r;
      default:
        throw new ServiceException("不识别的算数操作符");
    }
  }

  /**
   * 执行函数调用
   */
  private call(): any {
    // 函数名
    const name: string = this.value as string;

    // 如果是 where 函数，调用 where 过滤
    if (name === "where") {
      return this.where();
    }

    // 如果是 sum 求和函数，调用 sum 求和
    if (name === "sum") {
      return this.sum();
    }

    const objExp: Expression = this.children[0] as Expression;
    // 获取对象
    const obj: any = objExp.invoke();

    if (obj == null) {
      throw new ServiceException(`对象[${objExp.value}]为null`);
    }

    // 获得参数计算结果
    const params: any[] = [];
    for (let i = 1; i < this.children.length; i++) {
      const paramExp: Expression = this.children[i] as Expression;
      params.push(paramExp.invoke());
    }

    if (name === "runExpression") {
      let params1: string = params[0];
      params[0] = params1.replace("'", "$");
      params.push(this.delegate?.getObjectNames());
    }

    // 转换参数类型
    const types: any[] = new Array(params.length);
    for (let i = 0; i < params.length; i++) {
      const param = params[i];
      types[i] = param == null ? null : param.constructor;
    }

    // 查找对象方法
    const method = this.getMethod(obj, name, types);
    if (!method) {
      let error = `找不到方法: ${obj.constructor.name}.${name}(`;
      // 添加方法参数
      types.forEach(t => {
        error += t ? `${t.name},` : "null,";
      });
      error += ")";
      throw new ServiceException(error);
    }

    // 调用方法并处理返回值
    const oCall = method.apply(obj, params);
    if (oCall instanceof Promise) {
      return oCall.then(result => this.convert(result));
    } else {
      return this.convert(oCall);
    }
  }

  /**
   * 查找与给定方法名和参数类型匹配的方法
   */
  private getMethod(obj: any, methodName: string, paramTypes: any[]): Function | null {
    // 获取对象自身的所有属性名
    let methods = Object.getOwnPropertyNames(obj).filter(prop => typeof obj[prop] === 'function');

    // 获取对象的原型
    let proto = Object.getPrototypeOf(obj);

    // 递归获取原型链上的所有方法
    while (proto !== null) {
      methods = methods.concat(
        Object.getOwnPropertyNames(proto)
          .filter(prop => !['caller', 'callee', 'arguments'].includes(prop)) // 先排除
          .filter(prop => {
            try {
              return typeof proto[prop] === 'function' // 再判断是否为函数
            } catch (e) {
              return false // 避免 TypeError
            }
          })
      )
      proto = Object.getPrototypeOf(proto)
    }

    // 去重
    methods = [...new Set(methods)];

    for (const methodNameInObj of methods) {
      if (methodNameInObj === methodName) {
        const method = obj[methodNameInObj];
        if (this.matchParameterTypes(method, paramTypes)) {
          return method;
        }
      }
    }
    return null;
  }

  /**
   * 判断方法的参数类型是否与给定的类型匹配
   */
  private matchParameterTypes(method: Function, paramTypes: any[]): boolean {
    return true;
  }

  public setDelegate(delegate: Delegate): void {
    this.delegate = delegate;
  }

  private isNumberC(value: string): boolean {
    return !isNaN(Number(value)); // 判断 value 是否可以转成有效的数字
  }
}
