'use strict'

const ONE_MINUTE_IN_MILLIS = 60 * 1000

/**
 * @template T
 * @param {(...args: any[]) => T} func
 * @param {{maxCallsPerTimeSpan?: number, now?: {nowService: () => number}, timeSpan?: number}} [options]
 * @returns {(...args: any[]) => (T|undefined)}
 */
function makeThrottledFunction(
  func,
  {maxCallsPerTimeSpan = 120, now: nowService = Date.now, timeSpan = ONE_MINUTE_IN_MILLIS},
) {
  let start = nowService()
  let countLogsInMinute = 0
  let loggedWarning = false

  return function (...args) {
    if (nowService() - start >= timeSpan) {
      start = nowService()
      countLogsInMinute = 0
      loggedWarning = false
    }
    ++countLogsInMinute
    if (countLogsInMinute > maxCallsPerTimeSpan) {
      if (!loggedWarning) {
        func('throttling debug messages because max of %d exceeded', maxCallsPerTimeSpan)
        loggedWarning = true
      }
    } else {
      return func(...args)
    }
  }
}

module.exports = makeThrottledFunction
