import * as utils from './utils.js'

export default class Watcher {

    async stopWatching(unfullfilledTimeout) {
        if (unfullfilledTimeout) {
            let waitFullfilledStart = new Date().getTime();
            let waitFullfilledRunTime = 0;
            let isFullfilled = false;
            while (!isFullfilled && (waitFullfilledRunTime < unfullfilledTimeout)) {
                isFullfilled = true;
                this.watchScenarios.forEach(watchScenario => {
                    if (watchScenario.unfullfilled.size > 0) {
                        isFullfilled = false;
                    }
                });
                await utils.delay(500);
                waitFullfilledRunTime = new Date().getTime() - waitFullfilledStart;
            }
        }
        this.running = false;
        while (!this.finished) {
            await utils.delay(100);
        }
        this.outcomes = new Array();
        let errorMessage = '';
        let errorCount = 0;
        this.watchScenarios.forEach(watchScenario => {
            watchScenario.outcomes.forEach(outcome => {
                this.outcomes.push(outcome);
                if (outcome.failtest) {
                    errorCount += 1;
                    errorMessage = errorMessage + '\r\n' + outcome.message;
                }
            });
            watchScenario.unfullfilled.forEach((value, key) => {
                errorCount += 1;
                errorMessage = errorMessage + '\r\n' + value;
            });
        });
        if (errorCount > 0) {
           throw new Error(errorCount + ' WATCHER FAILURE(S) occured during this test:' + errorMessage);
        } else {
            return this.outcomes;
        }
    }

    async startWatching( watchScenarios, watcherInterval = 1000 ) {
      this.running = true;
      this.finished = false;
      this.watchScenarios = watchScenarios;
      let runStart = 0;
      let runTime = 0;
      while ( this.running ) {
          runStart = new Date().getTime();
          let promises = new Array();
          this.watchScenarios.forEach(watchScenario => {
            promises.push(watchScenario.execute());
          });
          await Promise.all(promises);
          runTime = new Date().getTime() - runStart;
          if (this.running && !(runTime > watcherInterval)) {
              await utils.delay(watcherInterval - runTime);
          }
      }
      this.finished = true;
  }
}
