/** A simple Least Recently Used map */
class LRUMap {

   constructor(  _maxSize) {this._maxSize = _maxSize;
    this._cache = new Map();
  }

  /** Get the current size of the cache */
   get size() {
    return this._cache.size;
  }

  /** Get an entry or undefined if it was not in the cache. Re-inserts to update the recently used order */
   get(key) {
    const value = this._cache.get(key);
    if (value === undefined) {
      return undefined;
    }
    // Remove and re-insert to update the order
    this._cache.delete(key);
    this._cache.set(key, value);
    return value;
  }

  /** Insert an entry and evict an older entry if we've reached maxSize */
   set(key, value) {
    if (this._cache.size >= this._maxSize) {
      // keys() returns an iterator in insertion order so keys().next() gives us the oldest key
      this._cache.delete(this._cache.keys().next().value);
    }
    this._cache.set(key, value);
  }

  /** Remove an entry and return the entry if it was in the cache */
   remove(key) {
    const value = this._cache.get(key);
    if (value) {
      this._cache.delete(key);
    }
    return value;
  }

  /** Clear all entries */
   clear() {
    this._cache.clear();
  }

  /** Get all the keys */
   keys() {
    return Array.from(this._cache.keys());
  }

  /** Get all the values */
   values() {
    const values = [];
    this._cache.forEach(value => values.push(value));
    return values;
  }
}

export { LRUMap };
