import * as plugins from './tapbundle.plugins.js';
import { TapTest } from './tapbundle.classes.taptest.js';

export interface IPromiseFunc {
  (): Promise<any>;
}

export class TapTools {
  /**
   * the referenced TapTest
   */
  private _tapTest: TapTest;

  constructor(TapTestArg: TapTest<any>) {
    this._tapTest = TapTestArg;
  }

  /**
   * allow failure
   */
  public allowFailure() {
    this._tapTest.failureAllowed = true;
  }

  /**
   * async/await delay method
   */
  public async delayFor(timeMilliArg: number) {
    await plugins.smartdelay.delayFor(timeMilliArg);
  }

  public async delayForRandom(timeMilliMinArg: number, timeMilliMaxArg: number) {
    await plugins.smartdelay.delayForRandom(timeMilliMinArg, timeMilliMaxArg);
  }

  public async coloredString(...args: Parameters<typeof plugins.consolecolor.coloredString>) {
    return plugins.consolecolor.coloredString(...args);
  }

  public async timeout(timeMilliArg: number) {
    const timeout = new plugins.smartdelay.Timeout(timeMilliArg);
    timeout.makeUnrefed();
    await timeout.promise;
    if (this._tapTest.status === 'pending') {
      this._tapTest.status = 'timeout';
    }
  }

  public async returnError(throwingFuncArg: IPromiseFunc) {
    let funcErr: Error;
    try {
      await throwingFuncArg();
    } catch (err: any) {
      funcErr = err;
    }
    return funcErr;
  }

  public defer() {
    return plugins.smartpromise.defer();
  }

  public cumulativeDefer() {
    return plugins.smartpromise.cumulativeDefer();
  }

  public smartjson = plugins.smartjson;
}
