/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {Observable} from 'rxjs';
import {filter, take} from 'rxjs/operators';
import {assertIsDefined} from './common-util';

/**
 * @param fn An iteratee function to be passed each element of
 *     the array in order. Must return a promise, and the following
 *     iteration will not begin until resolution of the promise returned by
 *     the previous iteration.
 *
 *     An optional second argument to fn is a callback that will halt the
 *     loop if called.
 */
export function asyncForeach<T>(
  array: T[],
  fn: (item: T, stopCallback: () => void) => Promise<unknown>
): Promise<T | void> {
  if (!array.length) {
    return Promise.resolve();
  }
  let stop = false;
  const stopCallback = () => {
    stop = true;
  };
  return fn(array[0], stopCallback).then(() => {
    if (stop) {
      return Promise.resolve();
    }
    return asyncForeach(array.slice(1), fn);
  });
}

export const _testOnly_allTasks = new Map<number, DelayedTask>();

/**
 * This is just a very simple and small wrapper around setTimeout(). Instead of
 * the usual:
 *
 * const timer = window.setTimeout(() => {...do stuff...}, 123);
 * window.clearTimeout(timer);
 *
 * With this class you can do:
 *
 * const task = new Task(() => {...do stuff...}, 123);
 * task.cancel();
 *
 * It is just nicer to have an object for this instead of a number as a handle.
 */
export class DelayedTask {
  private timer?: number;

  constructor(private callback: () => void, waitMs = 0) {
    this.timer = window.setTimeout(() => {
      if (this.timer) _testOnly_allTasks.delete(this.timer);
      this.timer = undefined;
      if (this.callback) this.callback();
    }, waitMs);
    _testOnly_allTasks.set(this.timer, this);
  }

  cancel() {
    if (this.isActive()) {
      window.clearTimeout(this.timer);
      if (this.timer) _testOnly_allTasks.delete(this.timer);
      this.timer = undefined;
    }
  }

  flush() {
    if (this.isActive()) {
      this.cancel();
      if (this.callback) this.callback();
    }
  }

  isActive() {
    return this.timer !== undefined;
  }
}

/**
 * The usage pattern is:
 *
 * this.myDebouncedTask = debounce(this.myDebouncedTask, () => {...}, 123);
 *
 * It is identical to:
 *
 * this.myTask = new DelayedTask(() => {...}, 123);
 *
 * But it would cancel a potentially scheduled task beforehand.
 */
export function debounce(
  existingTask: DelayedTask | undefined,
  callback: () => void,
  waitMs = 0
) {
  existingTask?.cancel();
  return new DelayedTask(callback, waitMs);
}

export const DELAYED_CANCELLATION = Symbol('Delayed Cancellation');

export class DelayedPromise<T> extends Promise<T> {
  private resolve: (value: PromiseLike<T> | T) => void;

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  private reject: (reason?: any) => void;

  private timer: number | undefined;

  constructor(private readonly callback: () => Promise<T>, waitMs = 0) {
    let resolve: ((value: PromiseLike<T> | T) => void) | undefined;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let reject: ((reason?: any) => void) | undefined;
    super((res, rej) => {
      resolve = res;
      reject = rej;
    });
    assertIsDefined(resolve);
    assertIsDefined(reject);
    this.resolve = resolve;
    this.reject = reject;
    this.timer = window.setTimeout(async () => {
      await this.flush();
    }, waitMs);
  }

  private stop() {
    if (this.timer === undefined) return false;
    window.clearTimeout(this.timer);
    this.timer = undefined;
    return true;
  }

  async flush() {
    if (!this.stop()) return;
    try {
      this.resolve(await this.callback());
    } catch (e) {
      this.reject(e);
    }
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  cancel(reason?: any) {
    if (!this.stop()) return;
    this.reject(reason ?? DELAYED_CANCELLATION);
  }

  delegate(other: Promise<T>) {
    if (!this.stop()) return;
    other
      .then((value: T) => this.resolve(value))
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      .catch((reason?: any) => this.reject(reason));
  }

  // From ECMAScript specification:
  // https://tc39.es/ecma262/#sec-get-promise-@@species
  //    Promise prototype methods normally use their this value's constructor to
  //    create a derived object. However, a subclass constructor may over-ride
  //    that default behaviour by redefining its @@species property.
  // NOTE: This is required otherwise .then and .catch on a DelayedPromise
  // will try to instantiate a DelayedPromise with 'resolve, reject' arguments.
  static override get [Symbol.species]() {
    return Promise;
  }

  override get [Symbol.toStringTag]() {
    return 'DelayedPromise';
  }
}

/**
 * The usage pattern is
 * this.aDebouncedPromise = debounceP(this.aDebouncedPromise, () => {...}, 123)
 */
export function debounceP<T>(
  existingPromise: DelayedPromise<T> | undefined,
  callback: () => Promise<T>,
  waitMs = 0
): DelayedPromise<T> {
  const promise = new DelayedPromise<T>(callback, waitMs);
  if (existingPromise) existingPromise.delegate(promise);
  return promise;
}
const THROTTLE_INTERVAL_MS = 500;

/**
 * Ensure only one call is made within THROTTLE_INTERVAL_MS and any call within
 * this interval is ignored
 */
export function throttleWrap<T>(fn: (e: T) => void) {
  let lastCall: number | undefined;
  return (e: T) => {
    if (
      lastCall !== undefined &&
      Date.now() - lastCall < THROTTLE_INTERVAL_MS
    ) {
      return;
    }
    lastCall = Date.now();
    fn(e);
  };
}

/**
 * Let's you wait for an Observable to become true.
 */
export function until<T>(obs$: Observable<T>, predicate: (t: T) => boolean) {
  return new Promise<void>(resolve => {
    obs$.pipe(filter(predicate), take(1)).subscribe(() => {
      resolve();
    });
  });
}

export const isFalse = (b: boolean) => b === false;

export type PromiseResult<T> =
  | {status: 'fulfilled'; value: T}
  | {status: 'rejected'; reason: string};
export function isFulfilled<T>(
  promiseResult?: PromiseResult<T>
): promiseResult is PromiseResult<T> & {status: 'fulfilled'} {
  return promiseResult?.status === 'fulfilled';
}

// An equivalent to Promise.allSettled from ES2020.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
// TODO: Migrate our tooling to ES2020 and remove this method.
export function allSettled<T>(
  promises: Promise<T>[]
): Promise<PromiseResult<T>[]> {
  return Promise.all(
    promises.map(promise =>
      promise
        .then(value => ({status: 'fulfilled', value} as const))
        .catch(reason => ({status: 'rejected', reason} as const))
    )
  );
}

/**
 * Noop function that can be used to suppress the tsetse must-use-promises rule.
 *
 * Example Usage:
 *   async function x() {
 *     await doA();
 *     noAwait(doB());
 *   }
 */
export function noAwait(_: {then: Function} | null | undefined) {}

export interface CancelablePromise<T> extends Promise<T> {
  cancel(): void;
}

/**
 * Make the promise cancelable.
 *
 * Returns a promise with a `cancel()` method wrapped around `promise`.
 * Calling `cancel()` will reject the returned promise with
 * {isCancelled: true} synchronously. If the inner promise for a cancelled
 * promise resolves or rejects this is ignored.
 */
export function makeCancelable<T>(promise: Promise<T>) {
  // True if the promise is either resolved or reject (possibly cancelled)
  let isDone = false;

  let rejectPromise: (reason?: unknown) => void;

  const wrappedPromise: CancelablePromise<T> = new Promise(
    (resolve, reject) => {
      rejectPromise = reject;
      promise.then(
        val => {
          if (!isDone) resolve(val);
          isDone = true;
        },
        error => {
          if (!isDone) reject(error);
          isDone = true;
        }
      );
    }
  ) as CancelablePromise<T>;

  wrappedPromise.cancel = () => {
    if (isDone) return;
    rejectPromise({isCanceled: true});
    isDone = true;
  };
  return wrappedPromise;
}
