'use strict'

const RateLimit = require('./rate-limit')

function setRoutes({ rateLimit }, { server, metricInstance }) {
  const ipRateLimit = new RateLimit({
    // Exclude IPs for GitHub Camo, determined experimentally by running e.g.
    // `curl --insecure -u ":shields-secret" https://s0.shields-server.com/sys/rate-limit`
    safelist: /^(?:192\.30\.252\.\d+)|(?:140\.82\.115\.\d+)$/,
  })
  const badgeTypeRateLimit = new RateLimit({ maxHitsPerPeriod: 6000 })
  const refererRateLimit = new RateLimit({
    maxHitsPerPeriod: 600,
    safelist: /^https?:\/\/shields\.io\/$/,
  })

  server.handle((req, res, next) => {
    if (rateLimit) {
      const ip =
        (req.headers['x-forwarded-for'] || '').split(', ')[0] ||
        req.socket.remoteAddress
      const badgeType = req.url.split(/[/-]/).slice(0, 3).join('')
      const referer = req.headers.referer

      if (ipRateLimit.isBanned(ip, req, res)) {
        metricInstance.noteRateLimitExceeded('ip')
        return
      }
      if (badgeTypeRateLimit.isBanned(badgeType, req, res)) {
        metricInstance.noteRateLimitExceeded('badge_type')
        return
      }
      if (refererRateLimit.isBanned(referer, req, res)) {
        metricInstance.noteRateLimitExceeded('referrer')
        return
      }
    }

    next()
  })

  server.get('/sys/rate-limit', (req, res) => {
    res.json({
      ip: ipRateLimit.toJSON(),
      badgeType: badgeTypeRateLimit.toJSON(),
      referer: refererRateLimit.toJSON(),
    })
  })

  return function () {
    ipRateLimit.stop()
    badgeTypeRateLimit.stop()
    refererRateLimit.stop()
  }
}

module.exports = { setRoutes }
