//@ts-check

import { fetchContentLength } from "./fetchContentLength.mjs";

/**
 * Conditional size fetcher, which can be skipped by providing an intial size.
 * This function is only useful when used as part of a larger loading framework, when
 * files loading may or may not have access to size information, and you want a
 * consistent behavior regardless.
 * 
 * If `estimatedTotal` is passed, this is a no-op.
 * If `estimatedTotal` is not passed, the created function does a limited `fetch`
 * to attempt to retrieve the file size.
 * Repeated calls to the function will not repeat the fetch request.
 * The function is not guaranteed to succeed, the server has to play along by
 * sending the correct headers.
 * Ideally, `total` is passed instead to avoid this.
 * @see {fetchContentLength} decodeContentLength
 * @param {string} filePath
 * @param {number} estimatedTotal
 * @returns {()=>Promise<number>} a function that always returns the same promise
 */
export const makeFileSizeFetcher = (filePath, estimatedTotal = 0) => {
  /**
   * @type {Promise<number> | null}
   */
  let totalPromise = estimatedTotal ? Promise.resolve(estimatedTotal) : null;

  const fetchSize = () =>
    (totalPromise =
      totalPromise ||
      fetchContentLength(filePath).then(
        (fetchedTotal) => (estimatedTotal = fetchedTotal)
      ));

  return fetchSize;
};

export default makeFileSizeFetcher;
