const NPMAPI = require('./NPMAPI')
const createCache = require('./createCache')
const createMutex = require('./createMutex')

const NPMDownloadsCache = createCache('npmDownloads')

function fetchDailyDownloads(packageName) {
  console.log(`info: Fetching downloads for ${packageName}`)

  return NPMAPI.getJSON(`/downloads/point/last-week/${packageName}`).then(function (data) {
    return data && Math.round(data.downloads / 7)
  })
}

const PackageNotFound = 'PackageNotFound'

const fetchMutex = createMutex(function (packageName, callback) {
  fetchDailyDownloads(packageName).then(function (value) {
    if (value == null) {
      // Cache 404s for 5 minutes. This prevents us from making
      // unnecessary requests to the NPM API for bad package names.
      // In the worst case, a brand new package's downloads will be
      // available within 5 minutes.
      NPMDownloadsCache.set(packageName, PackageNotFound, 300, function () {
        callback(null, value)
      })
    } else {
      // Cache downloads for 1 minute.
      NPMDownloadsCache.set(packageName, value, 60, function () {
        callback(null, value)
      })
    }
  }, function (error) {
    // Do not cache errors.
    NPMDownloadsCache.del(packageName, function () {
      callback(error)
    })
  })
})

function getDailyDownloads(packageName, callback) {
  NPMDownloadsCache.get(packageName, function (error, value) {
    if (error || value != null) {
      callback(error, value === PackageNotFound ? null : value)
    } else {
      fetchMutex(packageName, packageName, callback)
    }
  })
}

module.exports = {
  getDaily: getDailyDownloads
}