// 内置函数库
declare namespace nasl.util {
  /* 类型转换与格式化函数 */
  /* 各基础数据类型之间转换 */
  export function Convert(value: null): <T extends never>() => T;
  /**
   * 返回格式化的数字字符串
   * @param doubleValue: 待格式化的数字
   * @param digits: 小数位数
   * @param omit: 是否省略小数位数为0的部分
   * @param showGroups: 是否显示千分位分隔符
   * @param fix: 前缀或后缀: prefix、suffix
   * @param unit: 前缀或后缀的内容
   */
  export function FormatNumber(doubleValue: Decimal | Long, digits: Long, omit: Boolean, showGroups: Boolean, fix: String, unit: String): String;
  /* 返回格式化的百分比 */
  export function FormatPercent(doubleValue: Decimal | Long, digits: Long, omit: Boolean, showGroups: Boolean): String;
  /* 返回格式化日期时间字符串 */
  /* @example nasl.util.FormatDateTime(nasl.util.CurrDateTime(), 'yyyy-MM-dd HH:mm:ss', 'global') */
  export function FormatDateTime(dateTime: DateTime, formatter: String, timeZone: string): String;
  /* 返回格式化日期字符串 */
  /* @example nasl.util.FormatDate(nasl.util.CurrDate(), 'yyyy-MM-dd') */
  export function FormatDate(date: Date, formatter: String): String;
  /* 返回格式化时间字符串 */
  /* @example nasl.util.FormatTime(nasl.util.CurrTime(), 'HH:mm:ss') */
  export function FormatTime(time: Time, formatter: String): String;
  /* 字符串转换成其他类型 */
  /* @example nasl.util.FromString<Date>('2021-01-01') */
  export function FromString<T extends Decimal | Date | Time | DateTime | Long | Boolean>(value: String): T;
  /* 各类型转换成字符串 */
  export function ToString(value: Any): String;

  /* 字符串函数 */
  export function Length(str1: String): Long;
  export function Length<K, V>(str1: Map<K, V>): Long;
  export function Length<T>(str1: List<T>): Long;
  /* 用于查找字符串中指定字段所在位置，常用的场景包括字符串匹配、字符串替换、数据校验等 */
  export function IndexOf(str: String, search: String, formIndex: Long, ignoreCase: Boolean): Long;
  export function Join(list: List<Any>, separator: String): String;
  export function LastIndexOf(str: String, search: String, ignoreCase: Boolean): Long;
  export function Replace(str: String, search: String, replace: String): String;
  export function Split(str: String, separator: String, trail: Boolean): List<String>;
  export function SubString(str: String, start: Long, length: Long): String;
  export function ToLower(str1: String): String;
  export function ToUpper(str1: String): String;
  export function Trim(str1: String): String;

  /* 日期与时间函数 */
  export function CurrDate(): Date;
  export function CurrDateTime(): DateTime;
  export function CurrTime(): Time;
  /**
  * 返回日期比较结果
  * @param date1: 日期1
  * @param date2: 日期2
  * @param calcType: 计算类型。计算两个日期时间之间的差值，支持年数('y')、季度数('q')、月数('m')、周数('w')、天数('d')、小时数('h')、分钟数('m')、秒数('s')。默认为天数。
  * @param isAbs: 是否返回绝对值，默认为 true
  * @returns 根据计算类型返回对应的差值
  */
  export function DateDiff<T extends Date | Time | DateTime>(dateTime1: T, dateTime2: T, calcType: 'y' | 'q' | 'm' | 'w' | 'd' | 'h' | 'm' | 's', isAbs: Boolean): Long;
  /* 为指定日期时间调整增加（减少）时间 */
  export function AlterDateTime<T extends Date | DateTime>(dateTime: T, option: 'Increase' | 'Decrease', amount: Long, unit: 'day' | 'week' | 'month' | 'quarter' | 'year'): T;
  /**
  * 按指定维度计算日期的序号。当输入为 DateTime 类型时，会把数据转到提供的时区的当地时间进行计算
  * @param dateTime: 日期或日期时间
  * @param metric: 计算维度，格式为'小日期单位-大日期单位'。日期单位包括：'year'、'quarter'、'month'、'week'、'day'。如设置 'week-year'，则返回当前日期是所在年的第几周, 'day-week'，则返回当前日期是所在周的第几天。
  */
  export function GetDateCount<T extends Date | DateTime>(dateTime: T, metric: String): Long;
  /**
  * 按“星期几”获取指定日期范围内的日子。当输入为 DateTime 类型时，会把数据转到提供的时区的当地时间进行计算。
  * @param startDate: 开始日期/日期时间
  * @param endDate: 结束日期/日期时间
  * @param target: 目标星期几，1-7分别代表周一到周日
  */
  export function GetSpecificDaysOfWeek<T extends Date | DateTime>(startDate: T, endDate: T, target: List<Long>): List<T>;

  // 列表（List）函数
  export function ListAdd<T, K extends T>(list: List<T>, item: K): void;
  export function ListAddAll<T>(list: List<T>, addList: List<T>): Long;
  export function ListContains<T, K extends T>(list: List<T>, item: K): Boolean;
  export function ListInsert<T, K extends T>(list: List<T>, index: Long, item: K): void;
  export function ListDistinct<T>(list: List<T>): List<T>;
  export function ListDistinctBy<A>(list: List<A>, by: List<{ items: Array<(elem: A) => any>; }>): List<A>;
  export function ListFilter<T>(list: List<T>, by: (item: T) => Boolean): List<T>;
  export function ListFind<T>(list: List<T>, by: (item: T) => Boolean): T;
  export function ListFindIndex<T>(list: List<T>, by: (item: T) => Boolean): Long;
  export function ListFlatten<T>(list: List<List<T>>): List<T>;
  export function ListGroupBy<A, K extends Boolean | Long | Decimal | String>(list: List<A>, by: (elem: A) => K): Map<K, List<A>>;
  export function ListHead<T>(list: List<T>): T;
  export function ListLast<T>(list: List<T>): T;
  export function ListMax<T extends Long | Decimal | String>(list: List<T>): T;
  export function ListMin<T extends Long | Decimal | String>(list: List<T>): T;
  export function ListReverse<T>(list: List<T>): List<T>;
  export function ListSlice<T>(list: List<T>, start: Long, end: Long): List<T>;
  /**
  * 对 list 进行排序
  * @param list: 待排序的列表
  * @param fns: 排序规则，可同时支持多个排序规则
  * @returns 排序后的列表
  * @example nasl.util.ListSort(list, (item) => ({ asc: true, by: item }));
  * @example nasl.util.ListSort(list, (item) => ({ asc: true, by: item.name }), (item) => ({ asc: false, by: item.age}));
  */
  export function ListSort<T>(list: List<T>, ...fns: ((item: T) => { asc: Boolean, by: Boolean | Long | Decimal | String | Date | Time | DateTime; })[]): List<T>;
  export function ListSum<T extends Long | Decimal>(list: List<T>): T;
  export function ListToMap<T, K extends Boolean | Long | Decimal | String, V>(map: List<T>, byKey: (elem: T) => K, byVal: (elem: T) => V): Map<K, V>;
  export function ListTransform<T0, T>(list: List<T0>, by: (elem: T0) => T): List<T>;
  export function ListGet<T>(list: List<T>, index: Long): T;
  export function ListRemove<T, K extends T>(list: List<T>, item: K): void;
  export function ListRemoveAt<T>(list: List<T>, index: Long): T;
  export function ListSet<T, K extends T>(list: List<T>, index: Long, item: K): T;
  /* 生成指定范围和步长的整数列表，参数 start、end、step 需为整数 */
  export function ListRange(start: Long, end: Long, step: Long): List<Long>;
  /* 生成指定长度的重复元素列表 */
  export function ListRepeat<T>(item: T, length: Long): List<T>;

  /* 映射（Map）函数 */
  export function MapContains<K, V>(map: Map<K, V>, key: K): Boolean;
  export function MapGet<K, V>(map: Map<K, V>, key: K): V;
  export function MapPut<K, V>(map: Map<K, V>, key: K, value: V): void;
  export function MapKeys<K, V>(map: Map<K, V>): List<K>;
  export function MapRemove<K, V>(map: Map<K, V>, key: K): void;
  export function MapValues<K, V>(map: Map<K, V>): List<V>;

  /* 枚举函数。项目中的枚举类型均定义在 app.enums 中 */
  /* 返回枚举value和text的List集合 */
  /* @example nasl.util.EnumToList<app.enums.UserSourceEnum>() */
  export function EnumToList<T extends Enums>(): List<{ text: String, value: String; }>;
  /* 返回枚举指定value的标题字符串 */
  export function EnumItemToText(value: Enums<Long | String>): String;

  /* 数学函数 */
  /**
  * 整数/小数 操作
  * @param mode: 'HalfUp' | 'TowardsZero' | 'TowardsInfinity' === '四舍五入' | '截断、向零取整，如 -2.6 取整为 -2' | '进位、向正负无穷取整，如 -1.1 取整为 -2'
  */
  export function Round(value: Decimal, mode: 'HalfUp' | 'TowardsZero' | 'TowardsInfinity'): Long;
  export function Ceil(value: Decimal): Integer;
  export function Floor(value: Decimal): Integer;
  export function Trunc(value: Decimal): Integer;
  export function TruncDivide(left: Decimal, right: Decimal): Integer;

  export function Abs(value: Integer): Integer;
  export function Abs(value: Decimal): Decimal;

  export function Pow(base: Decimal, exponent: Decimal): Decimal;
  export function Sqrt(value: Decimal): Decimal;
  export function Cbrt(value: Decimal): Decimal;
  /* 返回指定数字的自然对数 */
  export function Log(value: Decimal): Decimal;

  export function PadStart(str: String, targetLength: String, fillStr = " "): String;
  export function PadEnd(str: String, targetLength: String, fillStr = " "): String;
  export function TrimStart(str: String): String;
  export function TrimEnd(str: String): String;
  /* RandomInt 生成的数字为整数，如果需要指定位数的随机数，需要在数字前按照位数要求补 0 */
  export function RandomInt(start: Long, end: Long): Long;

  // 其他函数
  /**
   * （修改原数据）清除复杂对象中每个属性的数据（若输入是单个基础类型如 Integer 的值，则不做处理）
   * @param struct 待清除的数据
   * @param mode: 'deep': '保留层次结构，仅清除对象最深层的叶子结点（全为基本类型），将其设置为 null' | 'shallow': 不保留对象的层级结构，清理后的对象仅有第一层结构，值全部为 null。
   */
  export function Clear<T>(struct: T, mode: 'deep' | 'shallow' = 'deep'): T;
  export function Clone<T>(struct: T): T;
  /* 判断参数是否为有效值，null、空字符串、纯空格、长度为0的集合均不被视为有效值，传入多个参数时，判断是否全部都是有效值 */
  export function HasValue(...args: Any[]): Boolean;

  // New 系列函数使用
  /**
  * 生成新的列表，T 类型必填
  * @example const variable1 = nasl.util.NewList<Boolean | Long>([true, false, 1])
  */
  export function NewList<T>(args: T[]): List<T>;
  /**
  * 生成新的映射，K、T 类型必填
  * @example const variable1 = nasl.util.NewMap<String, Long>({'123': 456})
  */
  export function NewMap<K, T>(args: any): Map<K, T>;
  /**
  * 生成新的数据实体，T 类型必填
  * class Entity1 { id: Long; property1: String; property2: String;}
  * @example const variable1 = nasl.util.NewEntity<Entity1>({id: 123, property1: '123', property2: '456'})
  */
  export function NewEntity<T>(arg: T): T;
  /**
  * 生成新的结构体，T 类型必填
  * class Structure1 { id: Long; property1: String; property2: String;}
  * @example const variable1 = nasl.util.NewStructure<Structure1>({id: 123, property1: '123', property2: '456'})
  */
  export function NewStructure<T>(arg: T): T;
  /**
  * 生成新的匿名结构体, 无需定义类型
  * @example const variable1 = nasl.util.NewAnonymousStructure({property1: '123', property2: '456'})
  */
  export function NewAnonymousStructure(arg: Any): Any;
  /**
  * 输出日志
  * @example nasl.util.consoleLog('输出日志');
  */
  export function consoleLog(arg: Any): void;
  export function jsonSerialize(arg: Any): String;
  /**
  * JSON 反序列化, T 为返回值类型，必填
  * @example nasl.util.jsonDeserialize<Boolean>(variable1);
  */
  export function jsonDeserialize<T>(arg: String): T;

}
