"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.CacheEntry = void 0;
var _ = _interopRequireWildcard(require("lodash"));
var FileSystem = _interopRequireWildcard(require("expo-file-system"));
var _sha = _interopRequireDefault(require("crypto-js/sha1"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
const BASE_DIR = `${FileSystem.cacheDirectory}`;
class CacheEntry {
  constructor(uri, options) {
    this.uri = uri;
    this.options = options;
    this.path = undefined;
    this.isPathResolved = false;
  }

  /**
   * Get the path of the cached image, if it exists.
   * If the image is not cached, download it and cache it.
   * @returns {Promise<string | undefined>} The path of the cached image, or undefined if the download failed.
   */
  async getPath() {
    if (!this.isPathResolved) {
      const {
        uri,
        options
      } = this;
      const {
        path,
        exists,
        tmpPath
      } = await getCacheEntry(uri);
      if (exists) {
        this.path = path;
      } else {
        const result = await FileSystem.createDownloadResumable(uri, tmpPath, options).downloadAsync();
        if (result && result.status === 200) {
          await FileSystem.moveAsync({
            from: tmpPath,
            to: path
          });
          this.path = path;
        }
      }
      this.isPathResolved = true;
    }
    return this.path;
  }
}

/**
 * CacheManager is a class that manages the caching of images.
 */
exports.CacheEntry = CacheEntry;
class CacheManager {
  static entries = new Map();

  /**
   * Returns a CacheEntry object for the given uri and options.
   * If the entry does not exist, it is created.
   * @param {string} uri - The uri of the image to cache.
   * @param {DownloadOptions} options - The options for downloading the image.
   * @returns {CacheEntry} The CacheEntry object for the given uri and options.
   */
  static get(uri, options) {
    if (!CacheManager.entries.has(uri)) {
      CacheManager.entries.set(uri, new CacheEntry(uri, options));
    }
    return CacheManager.entries.get(uri);
  }

  /**
   * Clears the cache directory.
   * @returns {Promise<void>} A promise that resolves when the cache is cleared.
   */
  static async clearCache() {
    await FileSystem.deleteAsync(BASE_DIR, {
      idempotent: true
    });
    await FileSystem.makeDirectoryAsync(BASE_DIR);
    CacheManager.entries.clear();
  }

  /**
   * Gets the size of the cache directory.
   * @returns {Promise<number>} A promise that resolves with the size of the cache directory.
   * @throws {Error} If the cache directory is not found.
   */
  static async getCacheSize() {
    const result = await FileSystem.getInfoAsync(BASE_DIR);
    if (!result.exists) {
      throw new Error(`${BASE_DIR} not found`);
    }
    return result.size;
  }
}

/**
 * Returns an object containing information about the cache entry for the given uri.
 * @param {string} uri - The uri of the image to cache.
 * @returns {Promise<{ exists: boolean; path: string; tmpPath: string }>} An object containing information about the cache entry.
 */
exports.default = CacheManager;
const getCacheEntry = async uri => {
  // Extract filename and extension from uri
  const filename = uri.substring(uri.lastIndexOf("/"), uri.indexOf("?") === -1 ? uri.length : uri.indexOf("?"));
  const ext = filename.indexOf(".") === -1 ? ".jpg" : filename.substring(filename.lastIndexOf("."));
  // Set path and tmpPath
  const path = `${BASE_DIR}${(0, _sha.default)(uri)}${ext}`;
  const tmpPath = `${BASE_DIR}${(0, _sha.default)(uri)}-${_.uniqueId()}${ext}`;
  try {
    await FileSystem.makeDirectoryAsync(BASE_DIR);
  } catch (e) {
    // If directory already exists, do nothing
  }
  // Check if file exists
  const info = await FileSystem.getInfoAsync(path);
  const {
    exists
  } = info;
  return {
    exists,
    path,
    tmpPath
  };
};
//# sourceMappingURL=cache-manager.js.map