/*
 * Copyright (c) 2020 WildFireChat. All rights reserved.
 */

import Long from "long";

// 说明
// 1. 由于PC SDK 和 Web SDK 对java long类型的处理不一致 ，故引入本系列函数
// 2. PC SDK，messageUid转换为long类型（可参考long.js)，其他所有时间相关的字段，都转换成number
// 3. Web SDK，messageUid 以及所有时间相关的字段都转换为long类型
// 4. 为了将UI层代码统一，对所有相关字段进行比较 、运算等操作时，都必须由本序列函数处理
/**
 * 比较数值大小
 * @param {long | number | string} a
 * @param {long | number | string} b
 * @return {number} 相等返回0，a 大于 b 返回1，a 小于 b 返回-1
 */
export function compare(a, b) {
  const longA = Long.fromValue(a);
  const longB = Long.fromValue(b);
  return longA.compare(longB);
}

/**
 * 判断数值是否相等
 * @param {long | number | string} a
 * @param {long | number | string} b
 * @return {boolean} 相等返回true；否则返回false
 */
export function eq(a, b) {
  if (!_isLong(a) || !_isLong(b)) {
    return false;
  }
  return compare(a, b) === 0;
}

/**
 * 判断数值a是否大于b
 * @param {long | number | string} a
 * @param {long | number | string} b
 * @return {boolean} a大于b返回true；否则返回false
 */
export function gt(a, b) {
  if (!_isLong(a) || !_isLong(b)) {
    return false;
  }
  return compare(a, b) === 1;
}

/**
 * 判断数值a是否大于或等于b
 * @param {long | number | string} a
 * @param {long | number | string} b
 * @return {boolean} a大于或等于b返回true；否则返回false
 */
export function gte(a, b) {
  if (!_isLong(a) || !_isLong(b)) {
    return false;
  }
  return compare(a, b) >= 0;
}

/**
 * 判断数值a是否小于b
 * @param {long | number | string} a
 * @param {long | number | string} b
 * @return {boolean} a小于b返回true；否则返回false
 */
export function lt(a, b) {
  if (!_isLong(a) || !_isLong(b)) {
    return false;
  }
  return compare(a, b) === -1;
}

/**
 * 判断数值a是否小于或等于b
 * @param {long | number | string} a
 * @param {long | number | string} b
 * @return {boolean} a小于或者等于b返回true；否则返回false
 */
export function lte(a, b) {
  if (!_isLong(a) || !_isLong(b)) {
    return false;
  }
  return compare(a, b) <= 0;
}

/**
 * 将数值l转换成string类型
 * @param {long |  number | string} l
 * @return {string} 数值表示
 */
export function stringValue(l) {
  const longl = Long.fromValue(l);
  return longl.toString();
}

/**
 * 将数值l转换成long类型
 * @param {long |  number | string} l
 * @return {long} 数值表示
 */
export function longValue(value) {
  return Long.fromValue(value);
}

/**
 * 将数值l转换成number类型
 * @param {long | number | string} l
 * @return {number|l} 如果数值l小于等于{@code Number.MAX_SAFE_INTEGER}则返回对应的number，否则原样返回
 */
export function numberValue(l) {
  if (lte(l, Number.MAX_SAFE_INTEGER)) {
    const longl = Long.fromValue(l);
    return longl.toNumber();
  } else {
    console.log(l, "is large than Number.MAX_SAFE_INTEGER, do nothing");
    return l;
  }
}

/**
 *
 * 由于Java long类型，在js里面，不能用number类型表示，故js里面采用js long对象表示
 * java long数据和js long对象序列成json格式的字符串时，格式并一样，为了处理跨平台需求，
 * 将序列化后的json格式字符串
 * java long "uid":12345678
 *
 * 当Java long类型的值，需要序列化为json字符串进行传输时，js long对象序列化出来的
 */
export function _patchToJavaLong(jsonStr, key) {
  if (!jsonStr) {
    return jsonStr;
  }

  let reg = new RegExp(`"${key}":"([0-9]+)"`, "g");
  // eslint-disable-next-line
  return jsonStr.replace(reg, `\"${key}\":$1`);
}

export function _reverseToJsLongString(jsonStr, key) {
  if (!jsonStr) {
    return jsonStr;
  }
  let reg = new RegExp(`"${key}":([0-9]+)`, "g");
  // eslint-disable-next-line
  return jsonStr.replace(reg, `\"${key}\":\"$1\"`);
}

function _isLong(val) {
  try {
    Long.fromValue(val);
    return true;
  } catch (e) {
    return false;
  }
}
