text: import Storage from './storage';
  import {requestConfigs} from '../config';
  
  /**
   * @description
   * Queue contains discovered handles for which bios have not yet
   * been requested.
   *
   * @name PendingQueue
   */
  class PendingQueue {
  
      /**
       * Get the pending queue
       * @returns {string[]}
       */
      static get queue() {
          return this._pendingQueue || [];
      }
  
      /**
       * Determine if queue is empty
       * @returns {boolean}
       */
      static get isEmpty() {
          return PendingQueue.queue.length === 0;
      }
  
      /**
       * Add a handle to pending queue
       * @param {string} value
       */
      static add(value) {
          this._pendingQueue = (PendingQueue.queue).concat([value]);
      }
  
      /**
       * Batch insert into queue
       * @param {string[]} values
       */
      static addAll(values) {
          this._pendingQueue = (PendingQueue.queue).concat(values);
      }
  
      /**
       * Whether given handle is currently in queue
       * @param {string} handle
       * @returns {boolean} - true for "yes, it is in queue"
       */
      static inQueue(handle) {
          return PendingQueue.queue.indexOf(handle) >= 0;
      }
  
      /**
       * Take allowed max number of names from the queue
       * @returns {string[]}
       */
      static takeNext() {
          const N = Math.min(PendingQueue.queue.length,
              requestConfigs.maxLookupCount);
          return PendingQueue.queue.splice(0, N);
      }
  
      /* @private */
      static clear() {
          this._pendingQueue = [];
      }
  }
  
  /**
   * @description
   * List of handles that have been checked during ongoing session
   * and will not be rechecked.
   *
   * @name HandledList
   */
  class HandledList {
  
      /**
       * Get the handles checklist
       * @returns {string[]}
       */
      static get list() {
          return this._handleCheckList || [];
      }
  
      /**
       * Add (multiple) handles to list of "already
       * processed". Once here that handle will not
       * be checked again.
       * @param values - array of handles
       */
      static add(values) {
          this._handleCheckList = (HandledList.list).concat(values);
      }
  
      /**
       * Remove (multiple) handles from list of "already
       * processed".
       * @param {string[]} values - array of handles
       */
      static remove(values) {
          this._handleCheckList = HandledList.list
              .filter(value => values.indexOf(value) < 0);
      }
  
      /**
       * Determine if handle has already been checked
       * for "compliance"
       * @param {string} handle
       * @returns {boolean} - true if already checked
       */
      static isChecked(handle) {
          return HandledList.list.indexOf(handle) >= 0;
      }
  
      /* @private */
      static clear() {
          this._handleCheckList = [];
      }
  }
  
  /**
   * @description
   * Whitelisted handles contain blocked words but user has manually
   * selected to not block them.
   *
   * @name WhiteList
   */
  class WhiteList {
  
      /**
       * Get the list of whitelisted handles
       * @returns {Object<string,string>}
       */
      static get whiteList() {
          return this._whiteList || {};
      }
  
      static set whiteList(value) {
          this._whiteList = value;
      }
  
      /**
       * Update client whitelist
       * @param {string} id
       * @param {string} handle
       */
      static add(id, handle) {
          Storage.addWhiteList({[id]: handle}, newList => {
              WhiteList.whiteList = newList;
          });
      }
  
      /**
       * Check if user id is whitelisted
       * @param {string} id
       * @returns {boolean}
       */
      static contains(id) {
          return !!WhiteList.whiteList[id];
      }
  }
  
  /**
   * @description
   * Manage blocker state
   *
   * @module
   * @name BlockerState
   */
  export default class BlockerState {
  
      /**
       * @description
       * Get list of handles that have already been checked during current
       * session, meaning bio was requested and checked for blocking.
       *
       * @returns {HandledList}
       */
      static get handledList() {
          return HandledList;
      }
  
      /**
       * Get the queue that holds discovered handles waiting to be processed.
       * When handle is in queue, the handle has been found, but bio has not
       * been checked yet.
       *
       * @returns {PendingQueue}
       */
      static get pendingQueue() {
          return PendingQueue;
      }
  
      /**
       * Get the list of whitelisted handles. Whitelisted handles may contain
       * block words, but user has explicitly bypassed the block on this user.
       *
       * @returns {WhiteList}
       */
      static get whiteList() {
          return WhiteList;
      }
  
      /**
       * Get/set the timestamp of last API bio request.
       *
       * @returns {number|undefined} - if undefined,
       * request had never been made
       */
      static get lastBioTimestamp() {
          return this._bioRequest;
      }
  
      static set lastBioTimestamp(value) {
          this._bioRequest = value;
      }
  
      /**
       * Whether it has been "long enough" since last bio request.
       *
       * @readonly
       * @returns {boolean} - true when it has been long enough.
       */
      static get lastBioExpired() {
          const diff = Date.now() - BlockerState.lastBioTimestamp;
          return Math.abs(diff) > requestConfigs.maxInterval;
      }
  
      /**
       * Get/set API tokens
       * @returns {Object}
       */
      static get tokens() {
          return this._tokens;
      }
  
      static set tokens(value) {
          this._tokens = value;
      }
  
      /**
       * @description
       * Check if module is ready to make API calls (true/false).
       *
       * It needs API tokens from background first and getting them is an
       * async process. Once the API tokens have been gathered, this method
       * will return true, and subsequent API calls should succeed.
       *
       * @readonly
       * @returns {boolean} - true when ready to call API
       */
      static get ready() {
          return !!(BlockerState.tokens &&
              BlockerState.tokens.csrfToken &&
              BlockerState.tokens.bearerToken);
      }
  
      /**
       * Get/set the list of flagged words that lead to blocking
       * @returns {string[]}
       */
      static get keyList() {
          return this._keyList;
      }
  
      static set keyList(value) {
          this._keyList = value;
      }
  
      /**
       * Get/set confirmation setting
       * @returns {Boolean}
       */
      static get confirmBlocks() {
          return this._confirm;
      }
  
      static set confirmBlocks(value) {
          this._confirm = value;
      }
  }
  
  