/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

module.exports = function (BLOCK_INTERVAL_MS, MAX_BAD_LOGINS, now) {

  now = now || Date.now

  function IpEmailRecord() {
    this.xs = []
  }

  IpEmailRecord.parse = function (object) {
    var rec = new IpEmailRecord()
    object = object || {}
    rec.bk = object.bk
    rec.xs = object.xs || []
    return rec
  }

  IpEmailRecord.prototype.isOverBadLogins = function () {
    this.trimBadLogins(now())
    return this.xs.length > MAX_BAD_LOGINS
  }

  IpEmailRecord.prototype.addBadLogin = function () {
    this.trimBadLogins(now())
    this.xs.push(now())
  }

  IpEmailRecord.prototype.trimBadLogins = function (now) {
    if (this.xs.length === 0) { return }
    // xs is naturally ordered from oldest to newest
    // and we only need to keep up to MAX_BAD_LOGINS + 1

    // start at the end and go backwards until login is old
    // or we have
    var i = this.xs.length - 1
    var n = 0
    var login = this.xs[i]
    while (login > (now - BLOCK_INTERVAL_MS) && n <= MAX_BAD_LOGINS) {
      login = this.xs[--i]
      n++
    }
    this.xs = this.xs.slice(i + 1)
  }

  IpEmailRecord.prototype.isBlocked = function () {
    return !!(this.bk && (now() - this.bk < BLOCK_INTERVAL_MS))
  }

  IpEmailRecord.prototype.block = function () {
    this.bk = now()
    this.xs = []
  }

  IpEmailRecord.prototype.unblockIfReset = function (resetAt) {
    if (resetAt > this.bk) {
      this.xs = []
      delete this.bk
    }
  }

  IpEmailRecord.prototype.retryAfter = function () {
    return Math.floor((this.bk + BLOCK_INTERVAL_MS - now()) / 1000)
  }

  IpEmailRecord.prototype.update = function (action) {
    if (!(
      action === 'accountLogin' ||
      action === 'accountDestroy' ||
      action === 'passwordChange'
      )) { return 0 }
    if (!this.isBlocked()) {
      if (this.isOverBadLogins()) {
        this.block()
      }
      else {
        return 0
      }
    }
    return this.retryAfter()
  }

  return IpEmailRecord
}

@@ -1703,16 +1703,28 @@
   return
+ Math.max(0,
  Math.fl
@@ -1728,23 +1728,30 @@
 .floor((
+(
 this.bk
+ %7C%7C 0)
  + BLOCK
@@ -1779,16 +1779,17 @@
  / 1000)
+)
 %0A  %7D%0A%0A  

Copy the retryAfter function from email_record.js