import { Environment } from '@/environment';
import { GatewayRegisterCenterService } from '../../interface';

/**
 * nacos地址服务
 *
 * @author chitanda
 * @date 2021-08-12 10:08:03
 * @export
 * @class GatewayService
 */
export class GatewayService {
  /**
   * 全局唯一实例
   *
   * @author chitanda
   * @date 2021-08-15 18:08:44
   * @protected
   * @static
   */
  protected static instance: GatewayService;

  /**
   * 当前轮询的服务器记录
   *
   * @author chitanda
   * @date 2021-08-12 12:08:27
   * @protected
   * @type {Map<string, number>}
   */
  protected indexes: Map<string, number> = new Map();

  /**
   * 服务注册中心
   *
   * @author chitanda
   * @date 2022-04-02 10:04:28
   * @protected
   * @type {GatewayRegisterCenterService}
   */
  protected registerCenter: GatewayRegisterCenterService;

  /**
   * 初始化
   *
   * @author chitanda
   * @date 2021-08-17 16:08:16
   */
  init(registerCenter: GatewayRegisterCenterService): void {
    this.registerCenter = registerCenter;
  }

  /**
   * 获取服务请求地址
   *
   * @author chitanda
   * @date 2021-08-12 12:08:55
   * @param {string} tag
   * @param {('random' | 'roundRobin')} [type='roundRobin']
   * @return {*}  {string}
   */
  getHost(tag: string, type: 'random' | 'roundRobin' = 'roundRobin'): string {
    if (!this.registerCenter) {
      return Environment.DefaultAPI.Address;
    }
    const ips = this.registerCenter.getAddress(tag) || [];
    if (ips.length > 0) {
      let host;
      if (type === 'random') {
        const i = Math.floor(Math.random() * ips.length);
        host = ips[i];
      } else if (type === 'roundRobin') {
        let i = 0;
        if (this.indexes.has(tag)) {
          i = this.indexes.get(tag);
        }
        if (i >= ips.length) {
          i = 0;
        }
        host = ips[i];
        this.indexes.set(tag, i);
      }
      return host;
    }
    return Environment.DefaultAPI.Address;
  }

  /**
   * 根据服务名称获取服务标识
   *
   * @author chitanda
   * @date 2022-04-02 10:04:08
   * @param {string} serviceName
   * @return {*}  {string}
   */
  getServiceId(serviceName: string): string {
    return this.registerCenter.getServiceId(serviceName);
  }

  /**
   * 获取唯一实例
   *
   * @author chitanda
   * @date 2021-08-15 18:08:26
   * @static
   * @return {*}  {GatewayService}
   */
  static getInstance(): GatewayService {
    if (!this.instance) {
      this.instance = new GatewayService();
    }
    return this.instance;
  }
}
