/** @format */

import { Eureka, EurekaClient } from 'eureka-js-client'

import client from './client'
import Pool from './pool'
const address = require('address')

interface IEureka {
  port: number
  appName: string
  services: string[]
  registerWithEureka?: boolean
}

const NODE_ENV = process.env.NODE_ENV || 'dev'

export default class Eurekaclient {
  private eureka!: Eureka
  private opts: IEureka
  private pool!: Pool
  constructor(options: IEureka) {
    options.services.push(options.appName)
    this.opts = options
    if (NODE_ENV) {
      this.eureka = client(options)
      this.pool = new Pool(this.eureka, this.opts.services)
    } else {
      console.log(`eureka use local`)
    }
  }

  /**
   * 启动eureka
   * @returns Promise<Eureka>
   */
  start() {
    const { opts, eureka } = this
    if (NODE_ENV) {
      eureka.start()
    }
    return new Promise<Eureka>(resolve => {
      console.log('Eureka checking...')
      let count = 1

      function checkHost() {
        // 超过检测次数，也返回成功（默认5秒）
        if (count >= 10) {
          resolve(eureka)
        }

        // 没有依赖服务，或已连通，立即返回成功
        if (opts.services.length === 0) {
          resolve(eureka)
        }

        setTimeout(() => {
          checkHost()
          count++
        }, 500)
      }
      checkHost()
    })
  }

  /**
   * stop
   */
  stop() {
    this.eureka.stop()
  }

  /**
   * 获取指定应用的ip
   * @param {(string | number)} name 应用名
   * @param {(string)} localIp 客户端IP
   * @param {string} [filterGroup] 要过滤的group service
   */
  getHost(name: string | number, localIp: string, filterGroup?: string) {
    if (!NODE_ENV) {
      const ip = address.ip()
      return `http://${ip}:${this.opts.port}`
    }
    return this.pool.getHost(name, localIp, filterGroup)
  }

  /** 获取代理信息(客户端IP, serviceGroupKey) */
  getProxyInfoFromReq(req: any) {
    const name = '_duibaServiceGroupKey'
    const reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)')

    // 获取多场景的cookie
    let arr = []
    let serviceGroupKey = ''
    if (req.headers.cookie && (arr = req.headers.cookie.match(reg))) {
      serviceGroupKey = unescape(arr[2])
    }

    // 获取客户端ip地址
    let ip =
      req.headers['x-real-ip'] ||
      req.headers['x-forwarded-for'] ||
      req.connection.remoteAddres ||
      req.socket.remoteAddress ||
      ''

    if (ip.indexOf('::ffff:') !== -1) {
      ip = ip.substring(7)
    }
    return { ip, serviceGroupKey }
  }
  /**
   * 获取所有eureka
   */
  getAllEurekas(): EurekaClient.EurekaInstanceConfig[] {
    return this.pool.getAllEurekas()
  }

  /**
   * 获取所有实例下的host
   */
  getAllHostName() {
    return this.pool.getAllHostName()
  }
}
