import { Service } from 'egg';
import { resResult as pubResult } from '../pubUtils/util';
import { gameData } from 'app/pubUtils/data';
import { RedisClient } from 'redis';
import { REDIS_KEY } from '@consts';
import { getRedisSubChannel } from 'app/pubUtils/sdkUtil';
const csprng = require('csprng');
/**
 * Utils Service
 */
export default class Utils extends Service {
  /**
   * 生成 len 长度的随机字符串
   * @param len 长度
   * @param radix 基数
   */
  public generateStr(len: number, radix = 36) {
    return `${csprng(len, radix)}`;
  }

  public genCode(len) {
    const chars = '123456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijklmnopqrstuvwxyz';
    const charArr = chars.split('');
    let code = '';
    for (let i = 0; i < len; i++) {
      code += charArr[Math.floor(Math.random() * charArr.length)];
    }
    return code;
  }

  /**
   * 生成指定长度的随机数
   * @param len 随机数长度
   */
  public generateNum(len: number) {
    let code = '';
    for (let i = 0; i < len; i++) {
      code += parseInt(`${Math.random() * 10}`);
    }
    return code;
  }

  public resResult(status: {code: number, simStr: string}, data?, customMsg?: string) {
    return pubResult(status, data, customMsg);
  }

  public log(level: 'DEBUG'|'INFO'|'WARN'| 'ERROR', message: string) {
    const log = this.app.loggers.get('linkLogger');

    if(level == 'DEBUG') {
      log.debug(`${message}`);
    } else if (level == 'INFO') {
      log.info(`${message}`);
    } else if (level == 'WARN') {
      log.warn(`${message}`);
    } else if (level == "ERROR") {
      log.error(`${message}`);
    }
  }

  public async checkOnlineUser(userCode: string) {
    let redisClient: RedisClient = this.ctx.app.context.redisClient;
    let onlineRoleId = await redisClient.hgetAsync(REDIS_KEY.USER_CODE, userCode);

    if (!!onlineRoleId) { // 多地登陆踢下线
      let str = await redisClient.hgetAsync(REDIS_KEY.ONLINE_USERS, onlineRoleId);

      if(str) {
          try {
              let [,sid] = str?.split('|')??[];
              let name = getRedisSubChannel(REDIS_KEY.USER_CHANNEL, this.ctx.app.config.env);
              await redisClient.publishAsync(name, `${sid}|${onlineRoleId}`);
          } catch(e) {
              console.error('checkOnlineUser', e);
          }
      }
    }    
  }

  // 检测是否可以登录
  public async validateCanLogin() {
    if(gameData.serverConst.CLOSE_LOGIN == 1) return false;
    if(gameData.serverConst.CLOSE_LOGIN_WHEN_ONLINE_MAX) {

      let redisClient: RedisClient = this.ctx.app.context.redisClient;
      let count = await redisClient.hlenAsync(REDIS_KEY.ONLINE_USERS);

      if(count >= gameData.serverConst.MAX_ONLINE_USER_COUNT) {
        return false
      }
    }
    return true;
  }

  // 比较以 . 分隔的版本号。返回 0 则版本号相等，返回正数则 versionA 大，返回负数则 versionB 大
  public compareVersion (versionA: string, versionB: string) {
    var vA = versionA.split('.');
    var vB = versionB.split('.');
    for (var i = 0; i < vA.length; ++i) {
        var a = parseInt(vA[i]);
        var b = parseInt(vB[i] || '0');
        if (a === b) {

        } else {
            return a - b;
        }
    }
    if (vB.length > vA.length) {
        return -1;
    } else {
        return 0;
    }
  };
}
