const url = require('url')
const pac = require('./source/pac')
const matchUtil = require('../../../utils/util.match')
const lodash = require('lodash')
function matched (hostname, regexpMap) {
  const ret1 = matchUtil.matchHostname(regexpMap, hostname)
  if (ret1) {
    return true
  }
  const ret = pac.FindProxyForURL('https://' + hostname, hostname)
  if (ret && ret.indexOf('PROXY ') === 0) {
    return true
  }
  return false
}

module.exports = function createOverWallIntercept (overWallConfig) {
  if (!overWallConfig || overWallConfig.enabled !== true) {
    return null
  }
  let server = overWallConfig.server
  let keys = Object.keys(server)
  if (keys.length === 0) {
    server = overWallConfig.serverDefault
    keys = Object.keys(server)
  }
  if (keys.length === 0) {
    return null
  }
  const regexpMap = matchUtil.domainMapRegexply(overWallConfig.targets)
  return {
    sslConnectInterceptor: (req, cltSocket, head) => {
      const hostname = req.url.split(':')[0]
      return matched(hostname, regexpMap)
    },
    requestIntercept (context, req, res, ssl, next) {
      const { rOptions, log, RequestCounter } = context
      if (rOptions.protocol === 'http:') {
        return
      }
      const hostname = rOptions.hostname
      if (!matched(hostname, regexpMap)) {
        return
      }
      const cacheKey = '__over_wall_proxy__'
      let proxyServer = keys[0]
      if (RequestCounter && keys.length > 1) {
        const count = RequestCounter.getOrCreate(cacheKey, keys)
        if (count.value == null) {
          count.doRank()
        }
        if (count.value == null) {
          log.error('count value is null', count)
        } else {
          count.doCount(count.value)
          proxyServer = count.value
          context.requestCount = {
            key: cacheKey,
            value: count.value,
            count
          }
        }
      }

      const domain = proxyServer
      const path = server[domain].path
      const password = server[domain].password
      const proxyTarget = domain + '/' + path + '/' + hostname + req.url

      // const backup = interceptOpt.backup
      const proxy = proxyTarget.indexOf('http') === 0 ? proxyTarget : (rOptions.protocol + '//' + proxyTarget)
      // eslint-disable-next-line node/no-deprecated-api
      const URL = url.parse(proxy)
      rOptions.protocol = URL.protocol
      rOptions.hostname = URL.host
      rOptions.host = URL.host
      rOptions.headers.host = URL.host
      if (password) {
        rOptions.headers.dspassword = password
      }
      rOptions.path = URL.path
      if (URL.port == null) {
        rOptions.port = rOptions.protocol === 'https:' ? 443 : 80
      }
      log.info('OverWall:', rOptions.hostname, proxyTarget)
      if (context.requestCount) {
        log.debug('OverWall choice:', JSON.stringify(context.requestCount))
      }

      return true
    }
  }
}
