// Copyright 2018-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only

import EventEmitter from 'events';
import * as log from './logging/log';
import { clearTimeoutIfNecessary } from './util/clearTimeoutIfNecessary';

const POLL_INTERVAL_MS = 5 * 1000;
const IDLE_THRESHOLD_MS = 20;

export class IdleDetector extends EventEmitter {
  private handle: undefined | ReturnType<typeof requestIdleCallback>;
  private timeoutId: undefined | ReturnType<typeof setTimeout>;

  public start(): void {
    log.info('Start idle detector');
    this.scheduleNextCallback();
  }

  public stop(): void {
    if (!this.handle) {
      return;
    }

    log.info('Stop idle detector');
    this.clearScheduledCallbacks();
  }

  private clearScheduledCallbacks() {
    if (this.handle) {
      cancelIdleCallback(this.handle);
      delete this.handle;
    }

    clearTimeoutIfNecessary(this.timeoutId);
    delete this.timeoutId;
  }

  private scheduleNextCallback() {
    this.clearScheduledCallbacks();
    this.handle = window.requestIdleCallback(deadline => {
      const { didTimeout } = deadline;
      const timeRemaining = deadline.timeRemaining();
      const isIdle = timeRemaining >= IDLE_THRESHOLD_MS;
      this.timeoutId = setTimeout(
        () => this.scheduleNextCallback(),
        POLL_INTERVAL_MS
      );
      if (isIdle || didTimeout) {
        this.emit('idle', { timestamp: Date.now(), didTimeout, timeRemaining });
      }
    });
  }
}
