text: // @flow
  
  import JitsiMeetJS from '../lib-jitsi-meet';
  import { Platform } from '../react';
  
  const { browser } = JitsiMeetJS.util;
  
  const DEFAULT_OPTIMAL_BROWSERS = [
      'chrome',
      'electron',
      'firefox',
      'nwjs'
  ];
  
  const DEFAULT_UNSUPPORTED_BROWSERS = [];
  
  const browserNameToCheck = {
      chrome: browser.isChrome.bind(browser),
      chromium: browser.isChromiumBased.bind(browser),
      edge: browser.isEdge.bind(browser),
      electron: browser.isElectron.bind(browser),
      firefox: browser.isFirefox.bind(browser),
      nwjs: browser.isNWJS.bind(browser),
      opera: browser.isOpera.bind(browser),
      safari: browser.isSafari.bind(browser)
  };
  
  declare var interfaceConfig: Object;
  
  /**
   * Returns whether or not jitsi is optimized and targeted for the  provided
   * browser name.
   *
   * @param {string} browserName - The name of the browser to check.
   * @returns {boolean}
   */
  export function isBrowsersOptimal(browserName: string) {
      return (interfaceConfig.OPTIMAL_BROWSERS || DEFAULT_OPTIMAL_BROWSERS)
          .includes(browserName);
  }
  
  /**
   * Returns whether or not the current browser or the list of passed in browsers
   * is considered suboptimal. Suboptimal means it is a supported browser but has
   * not been explicitly listed as being optimal, possibly due to functionality
   * issues.
   *
   * @param {Array<string>} [browsers] - A list of browser names to check. Will
   * default to a whitelist.
   * @returns {boolean}
   */
  export function isSuboptimalBrowser() {
      const optimalBrowsers
          = interfaceConfig.OPTIMAL_BROWSERS || DEFAULT_OPTIMAL_BROWSERS;
  
      return !_isCurrentBrowserInList(optimalBrowsers) && isSupportedBrowser();
  }
  
  /**
   * Returns whether or not the current browser should allow the app to display.
   * A supported browser is assumed to be able to support WebRtc.
   *
   * @returns {boolean}
   */
  export function isSupportedBrowser() {
      if (navigator.product === 'ReactNative') {
          return false;
      }
  
      // Blacklists apply to desktop browsers only right now.
      if (!_isMobileBrowser() && _isCurrentBrowserInList(
          interfaceConfig.UNSUPPORTED_BROWSERS || DEFAULT_UNSUPPORTED_BROWSERS
      )) {
          return false;
      }
  
      // We are intentionally allow mobile browsers because:
      // - the WelcomePage is mobile ready;
      // - if the URL points to a conference then deep-linking will take
      //   care of it.
      return _isMobileBrowser() || JitsiMeetJS.isWebRtcSupported();
  }
  
  /**
   * Runs various browser checks to know if the current browser is found within
   * the list.
   *
   * @param {Array<string>} list - Browser names to check. The names should be
   * keys in {@link browserNameToCheck}.
   * @private
   * @returns {boolean}
   */
  function _isCurrentBrowserInList(list) {
      return Boolean(list.find(browserName => {
          const checkFunction = browserNameToCheck[browserName];
  
          return checkFunction ? checkFunction.call(browser) : false;
      }));
  }
  
  /**
   * Returns whether or not the current environment is a mobile device.
   *
   * @private
   * @returns {boolean}
   */
  function _isMobileBrowser() {
      return Platform.OS === 'android' || Platform.OS === 'ios';
  }
  