/**
 * A basic cache handler for Response objects. This should
 * be modified to vary the key based on application logic 
 * like "logged in user" or "account number"
 */

/**
 * Gets an HTTP response from the cache
 * @param {string} key Key to retrieve
 * @returns {Response | null}.
 */
export async function get(key) {
  let meta = await fly.cache.getString(key + ":meta")
  if (!meta) return null// cache miss
  try {
    meta = JSON.parse(meta)
  } catch (err) {
    return null// also a miss
  }

  let body = await fly.cache.get(key + ":body")
  if (!body) return null// miss
  if (meta.at) {
    meta.headers.Age = parseInt(Date.now() / 1000) - meta.at
    meta.headers['Fly-Age'] = meta.headers.Age
    delete meta.at
  }
  return new Response(body, meta)
}

const goodHeaders = [
  'content-type',
  'content-length',
  'content-encoding',
  'cache-control',
  'expires',
  'link',
  'set-cookie'
]
/**
 * Stores a Response in the cache
 * 
 * @param {string} key The key to store the response at
 * @param {Response} response An HTTP response to cache
 * @param {number | undefined} ttl Expire after seconds
 */
export async function set(key, response, ttl) {
  let meta = {
    status: response.status,
    headers: {},
    at: parseInt(Date.now() / 1000)
  }
  for (const h of goodHeaders) {
    const v = response.headers.getAll(h)
    if (v && v.length > 0) {
      meta.headers[h] = v.join(", ")
    }
  }

  const body = await response.clone().arrayBuffer()
  const result = Promise.all([
    fly.cache.set(key + ":meta", JSON.stringify(meta), ttl),
    fly.cache.set(key + ":body", body, ttl)
  ])

  return result[0] && result[1]
}

export default {
  get,
  set
}