var wrappy = require('wrappy') var reqs = Object.create(null) var once = require('once')

module.exports = wrappy(inflight)

function inflight (key, cb) {

if (reqs[key]) {
  reqs[key].push(cb)
  return null
} else {
  reqs[key] = [cb]
  return makeres(key)
}

}

function makeres (key) {

return once(function RES () {
  var cbs = reqs[key]
  var len = cbs.length
  var args = slice(arguments)

  // XXX It's somewhat ambiguous whether a new callback added in this
  // pass should be queued for later execution if something in the
  // list of callbacks throws, or if it should just be discarded.
  // However, it's such an edge case that it hardly matters, and either
  // choice is likely as surprising as the other.
  // As it happens, we do go ahead and schedule it for later execution.
  try {
    for (var i = 0; i < len; i++) {
      cbs[i].apply(null, args)
    }
  } finally {
    if (cbs.length > len) {
      // added more in the interim.
      // de-zalgo, just in case, but don't call again.
      cbs.splice(0, len)
      process.nextTick(function () {
        RES.apply(null, args)
      })
    } else {
      delete reqs[key]
    }
  }
})

}

function slice (args) {

var length = args.length
var array = []

for (var i = 0; i < length; i++) array[i] = args[i]
return array

}