/**
 * @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>();

export enum ResolvedDelayedTaskStatus {
  CALLBACK_EXECUTED = 'CALLBACK_EXECUTED',
  TASK_CANCELLED = 'TASK_CANCELLED',
}

/**
 * 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 timerId?: number;

  /**
   * Promise that is resolved after the callback is run or the task is
   * cancelled.
   *
   * If callback returns a Promise this resolves after the promise is settled.
   */
  public readonly promise: Promise<ResolvedDelayedTaskStatus>;

  private resolvePromise?: (
    value: ResolvedDelayedTaskStatus | PromiseLike<ResolvedDelayedTaskStatus>
  ) => void;

  private callCallbackAndResolveOnCompletion() {
    let callbackResult;
    if (this.callback) callbackResult = this.callback();
    if (callbackResult instanceof Promise) {
      callbackResult.finally(() => {
        this.resolvePromise!(ResolvedDelayedTaskStatus.CALLBACK_EXECUTED);
      });
    } else {
      this.resolvePromise!(ResolvedDelayedTaskStatus.CALLBACK_EXECUTED);
    }
  }

  constructor(
    private readonly callback: () => void | Promise<void>,
    waitMs = 0
  ) {
    this.promise = new Promise(resolve => {
      this.resolvePromise = resolve;
      this.timerId = window.setTimeout(() => {
        if (this.timerId) _testOnly_allTasks.delete(this.timerId);
        this.timerId = undefined;
        this.callCallbackAndResolveOnCompletion();
      }, waitMs);
      _testOnly_allTasks.set(this.timerId, this);
    });
  }

  private cancelTimer() {
    window.clearTimeout(this.timerId);
    if (this.timerId) _testOnly_allTasks.delete(this.timerId);
    this.timerId = undefined;
  }

  cancel() {
    if (this.isActive()) {
      this.cancelTimer();
      this.resolvePromise?.(ResolvedDelayedTaskStatus.TASK_CANCELLED);
    }
  }

  flush() {
    if (this.isActive()) {
      this.cancelTimer();
      this.callCallbackAndResolveOnCompletion();
    }
  }

  isActive() {
    return this.timerId !== 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;
}

export interface MockPromise<T> extends Promise<T> {
  resolve: (value?: T) => void;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  reject: (reason?: any) => void;
}

export function mockPromise<T = unknown>(): MockPromise<T> {
  let res: (value?: T) => void;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  let rej: (reason?: any) => void;
  const promise: MockPromise<T> = new Promise<T | undefined>(
    (resolve, reject) => {
      res = resolve;
      rej = reject;
    }
  ) as MockPromise<T>;
  promise.resolve = res!;
  promise.reject = rej!;
  return promise;
}

// MockPromise is the established name in tests, and we don't want to rename
// that in 50 files. But "Mock" is a bit misleading and definitely not a great
// fit for non-test code. So let's also export under a different name.
export type InteractivePromise<T> = MockPromise<T>;
export const interactivePromise = mockPromise;

export function timeoutPromise(timeoutMs: number): Promise<void> {
  return new Promise<void>(resolve => {
    setTimeout(resolve, timeoutMs);
  });
}

export async function waitUntil(
  predicate: (() => boolean) | (() => Promise<boolean>),
  message = 'The waitUntil() predicate is still false after 1000 ms.',
  timeout_ms = 1000
): Promise<void> {
  if (await predicate()) return Promise.resolve();
  const start = Date.now();
  let sleep = 10;
  const error = new Error(message);
  return new Promise((resolve, reject) => {
    const waiter = async () => {
      if (await predicate()) {
        resolve();
        return;
      }
      if (Date.now() - start >= timeout_ms) {
        reject(error);
        return;
      }
      setTimeout(waiter, sleep);
      sleep *= 2;
    };
    waiter();
  });
}
