"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.TeamcityReporter = exports.CreeveyReporter = void 0;
var _chalk = _interopRequireDefault(require("chalk"));
var _mocha = require("mocha");
var _loglevelPluginPrefix = _interopRequireDefault(require("loglevel-plugin-prefix"));
var _types = require("../../types");
var _logger = require("../logger");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const testLevels = {
  INFO: _chalk.default.green('PASS'),
  WARN: _chalk.default.yellow('START'),
  ERROR: _chalk.default.red('FAIL')
};
class CreeveyReporter extends _mocha.reporters.Base {
  constructor(runner, options) {
    super(runner);
    const {
      sessionId,
      topLevelSuite
    } = options.reporterOptions;
    const testLogger = (0, _logger.getLogger)(topLevelSuite);
    _loglevelPluginPrefix.default.apply(testLogger, {
      format(level) {
        return `${testLevels[level]} => (${topLevelSuite}:${_chalk.default.gray(sessionId)})`;
      }
    });
    runner.on('test', test => testLogger.warn(_chalk.default.cyan(test.titlePath().join('/'))));
    runner.on('pass', test => testLogger.info(_chalk.default.cyan(test.titlePath().join('/'))));
    runner.on('fail', (test, error) => testLogger.error(_chalk.default.cyan(test.titlePath().join('/')), '\n  ', getErrors(error, (error, imageName) => `${_chalk.default.bold(imageName ?? topLevelSuite)}:${error}`, error => `${error.stack ?? error.message}`).join('\n  ')));
  }
}
exports.CreeveyReporter = CreeveyReporter;
class TeamcityReporter extends _mocha.reporters.Base {
  constructor(runner, options) {
    super(runner);
    const topLevelSuite = this.escape(options.reporterOptions.topLevelSuite);
    const reporterOptions = options.reporterOptions;
    runner.on('suite', suite => suite.root ? console.log(`##teamcity[testSuiteStarted name='${topLevelSuite}' flowId='${process.pid}']`) : console.log(`##teamcity[testSuiteStarted name='${this.escape(suite.title)}' flowId='${process.pid}']`));
    runner.on('test', test => console.log(`##teamcity[testStarted name='${this.escape(test.title)}' flowId='${process.pid}']`));
    runner.on('fail', (test, error) => {
      Object.entries(reporterOptions.images).forEach(([name, image]) => {
        if (!image) return;
        const filePath = test.titlePath().concat(name == topLevelSuite ? [] : [topLevelSuite]).map(this.escape).join('/');
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const {
          error,
          ...rest
        } = image;
        Object.values(rest).filter(_types.isDefined).forEach(fileName => {
          console.log(`##teamcity[publishArtifacts '${reporterOptions.reportDir}/${filePath}/${fileName} => report/${filePath}']`);
          console.log(`##teamcity[testMetadata testName='${this.escape(test.title)}' type='image' value='report/${filePath}/${fileName}' flowId='${process.pid}']`);
        });
      });

      // Output failed test as passed due TC don't support retry mechanic
      // https://teamcity-support.jetbrains.com/hc/en-us/community/posts/207216829-Count-test-as-successful-if-at-least-one-try-is-successful?page=1#community_comment_207394125

      reporterOptions.willRetry ? console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`) : console.log(`##teamcity[testFailed name='${this.escape(test.title)}' message='${this.escape(error.message)}' details='${this.escape(error.stack ?? '')}' flowId='${process.pid}']`);
    });
    runner.on('pending', test => console.log(`##teamcity[testIgnored name='${this.escape(test.title)}' message='${this.escape(typeof test.skipReason == 'boolean' ? test.title : test.skipReason)}' flowId='${process.pid}']`));
    runner.on('test end', test => console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`));
    runner.on('suite end', suite => suite.root || console.log(`##teamcity[testSuiteFinished name='${this.escape(suite.title)}' flowId='${process.pid}']`));
    runner.on('end', () => console.log(`##teamcity[testSuiteFinished name='${topLevelSuite}' flowId='${process.pid}']`));
  }
  escape = str => {
    if (!str) return '';
    return str.toString()
    // eslint-disable-next-line no-control-regex
    .replace(/\x1B.*?m/g, '').replace(/\|/g, '||').replace(/\n/g, '|n').replace(/\r/g, '|r').replace(/\[/g, '|[').replace(/\]/g, '|]').replace(/\u0085/g, '|x').replace(/\u2028/g, '|l').replace(/\u2029/g, '|p').replace(/'/g, "|'");
  };
}
exports.TeamcityReporter = TeamcityReporter;
function getErrors(error, imageErrorToString, errorToString) {
  const errors = [];
  if (!(error instanceof Error)) {
    errors.push(error);
  } else if (!(0, _types.isImageError)(error)) {
    errors.push(errorToString(error));
  } else if (typeof error.images == 'string') {
    errors.push(imageErrorToString(error.images));
  } else {
    const imageErrors = error.images;
    Object.keys(imageErrors).forEach(imageName => {
      errors.push(imageErrorToString(imageErrors[imageName] ?? '', imageName));
    });
  }
  return errors;
}