import run from 'ember-runloop';

export default class BeforeUnloadGuard {
  constructor(win, message = true) {
    this._pendingPromiseCount = 0;
    this._win = win;
    this._message = message;
    this._onBeforeUnloadListener = run.bind(this, this._onBeforeUnload);
    this._win.addEventListener('beforeunload', this._onBeforeUnloadListener);
  }

  trackPromise(promise) {
    this._pendingPromiseCount++;
    promise.finally(() => this._pendingPromiseCount--);
  }

  teardown() {
    this._win.removeEventListener('beforeunload', this._onBeforeUnloadListener);
  }

  get hasPendingPromises() {
    return Boolean(this._pendingPromiseCount);
  }

  _onBeforeUnload(e) {
    if (this.hasPendingPromises) {
      // Support most browsers.
      // https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload#Examples
      //
      // Browsers that adhere to the current specification for beforeunload,
      // will not show the return value provided. However, some browers will
      // also show the return value.
      e.returnValue = this._message;
      return this._message;
    }
  }
}
