'use strict';

/*!
 * mocha
 * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

var escapeRe = require('escape-string-regexp');
var path = require('path');
var builtinReporters = require('./reporters');
var growl = require('./growl');
var utils = require('./utils');
var mocharc = require('./mocharc.json');
var errors = require('./errors');
var Suite = require('./suite');
var createStatsCollector = require('./stats-collector');
var createInvalidReporterError = errors.createInvalidReporterError;
var createInvalidInterfaceError = errors.createInvalidInterfaceError;
var EVENT_FILE_PRE_REQUIRE = Suite.constants.EVENT_FILE_PRE_REQUIRE;
var EVENT_FILE_POST_REQUIRE = Suite.constants.EVENT_FILE_POST_REQUIRE;
var EVENT_FILE_REQUIRE = Suite.constants.EVENT_FILE_REQUIRE;
var sQuote = utils.sQuote;

exports = module.exports = Mocha;

/**
 * To require local UIs and reporters when running in node.
 */

if (!process.browser) {
  var cwd = process.cwd();
  module.paths.push(cwd, path.join(cwd, 'node_modules'));
}

/**
 * Expose internals.
 */

/**
 * @public
 * @class utils
 * @memberof Mocha
 */
exports.utils = utils;
exports.interfaces = require('./interfaces');
/**
 * @public
 * @memberof Mocha
 */
exports.reporters = builtinReporters;
exports.Runnable = require('./runnable');
exports.Context = require('./context');
/**
 *
 * @memberof Mocha
 */
exports.Runner = require('./runner');
exports.Suite = Suite;
exports.Hook = require('./hook');
exports.Test = require('./test');

/**
 * Constructs a new Mocha instance with `options`.
 *
 * @public
 * @class Mocha
 * @param {Object} [options] - Settings object.
 * @param {boolean} [options.allowUncaught] - Propagate uncaught errors?
 * @param {boolean} [options.asyncOnly] - Force `done` callback or promise?
 * @param {boolean} [options.bail] - Bail after first test failure?
 * @param {boolean} [options.checkLeaks] - If true, check leaks.
 * @param {boolean} [options.delay] - Delay root suite execution?
 * @param {boolean} [options.enableTimeouts] - Enable timeouts?
 * @param {string} [options.fgrep] - Test filter given string.
 * @param {boolean} [options.forbidOnly] - Tests marked `only` fail the suite?
 * @param {boolean} [options.forbidPending] - Pending tests fail the suite?
 * @param {boolean} [options.fullStackTrace] - Full stacktrace upon failure?
 * @param {string[]} [options.global] - Variables expected in global scope.
 * @param {RegExp|string} [options.grep] - Test filter given regular expression.
 * @param {boolean} [options.growl] - Enable desktop notifications?
 * @param {boolean} [options.hideDiff] - Suppress diffs from failures?
 * @param {boolean} [options.ignoreLeaks] - Ignore global leaks?
 * @param {boolean} [options.invert] - Invert test filter matches?
 * @param {boolean} [options.noHighlighting] - Disable syntax highlighting?
 * @param {string} [options.reporter] - Reporter name.
 * @param {Object} [options.reporterOption] - Reporter settings object.
 * @param {number} [options.retries] - Number of times to retry failed tests.
 * @param {number} [options.slow] - Slow threshold value.
 * @param {number|string} [options.timeout] - Timeout threshold value.
 * @param {string} [options.ui] - Interface name.
 * @param {boolean} [options.color] - Color TTY output from reporter?
 * @param {boolean} [options.useInlineDiffs] - Use inline diffs?
 */
function Mocha(options) {
  options = utils.assign({}, mocharc, options || {});
  this.files = [];
  this.options = options;
  // root suite
  this.suite = new exports.Suite('', new exports.Context(), true);

  if ('useColors' in options) {
    utils.deprecate(
      'useColors is DEPRECATED and will be removed from a future version of Mocha. Instead, use the "color" option'
    );
    options.color = 'color' in options ? options.color : options.useColors;
  }

  // Globals are passed in as options.global, with options.globals for backward compatibility.
  options.globals = options.global || options.globals || [];
  delete options.global;

  this.grep(options.grep)
    .fgrep(options.fgrep)
    .ui(options.ui)
    .bail(options.bail)
    .reporter(options.reporter, options.reporterOptions)
    .useColors(options.color)
    .slow(options.slow)
    .useInlineDiffs(options.inlineDiffs)
    .globals(options.globals);

  if ('enableTimeouts' in options) {
    utils.deprecate(
      'enableTimeouts is DEPRECATED and will be removed from a future version of Mocha. Instead, use "timeout: false" to disable timeouts.'
    );
    if (options.enableTimeouts === false) {
      this.timeout(0);
    }
  }

  // this guard exists because Suite#timeout does not consider `undefined` to be valid input
  if (typeof options.timeout !== 'undefined') {
    this.timeout(options.timeout === false ? 0 : options.timeout);
  }

  if ('retries' in options) {
    this.retries(options.retries);
  }

  if ('diff' in options) {
    this.hideDiff(!options.diff);
  }

  [
    'allowUncaught',
    'asyncOnly',
    'checkLeaks',
    'delay',
    'forbidOnly',
    'forbidPending',
    'fullTrace',
    'growl',
    'invert'
  ].forEach(function(opt) {
    if (options[opt]) {
      this[opt]();
    }
  }, this);
}

/**
 * Enables or disables bailing on the first failure.
 *
 * @public
 * @see {@link https://mochajs.org/#-b---bail|CLI option}
 * @param {boolean} [bail=true] - Whether to bail on first error.
 * @returns {Mocha} this
 * @chainable
 */
Mocha.prototype.bail = function(bail) {
  if (!arguments.length) {
    bail = true;
  }
  this.suite.bail(bail);
  return this;
};

/**
 * @summary
 * Adds `file` to be loaded for execution.
 *
 * @description
 * Useful for generic setup code that must be included within test suite.
 *
 * @public
 * @see {@link https://mochajs.org/#--file-file|CLI option}
 * @param {string} file - Pathname of file to be loaded.
 * @returns {Mocha} this
 * @chainable
 */
Mocha.prototype.addFile = function(file) {
  this.files.push(file);
  return this;
};

/**
 * Sets reporter to `reporter`, defaults to "spec".
 *
 * @public
 * @see {@link https://mochajs.org/#-r---reporter-name|CLI option}
 * @see {@link https://mochajs.org/#reporters|Reporters}
 * @param {String|Function} reporter - Reporter name or constructor.
 * @param {Object} [reporterOptions] - Options used to configure the reporter.
 * @returns {Mocha} this
 * @chainable
 * @throws {Error} if requested reporter cannot be loaded
 * @example
 *
 * // Use XUnit reporter and direct its output to file
 * mocha.reporter('xunit', { output: '/path/to/testspec.xunit.xml' });
 */
Mocha.prototype.reporter = function(reporter, reporterOptions) {
  if (typeof reporter === 'function') {
    this._reporter = reporter;
  } else {
    reporter = reporter || 'spec';
    var _reporter;
    // Try to load a built-in reporter.
    if (builtinReporters[reporter]) {
      _reporter = builtinReporters[reporter];
    }
    // Try to load reporters from process.cwd() and node_modules
    if (!_reporter) {
      try {
        _reporter = require(reporter);
      } catch (err) {
        if (
          err.code !== 'MODULE_NOT_FOUND' ||
          err.message.indexOf('Cannot find module') !== -1
        ) {
          // Try to load reporters from a path (absolute or relative)
          try {
            _reporter = require(path.resolve(process.cwd(), reporter));
          } catch (_err) {
            _err.code !== 'MODULE_NOT_FOUND' ||
            _err.message.indexOf('Cannot find module') !== -1
              ? console.warn(sQuote(reporter) + ' reporter not found')
              : console.warn(
                  sQuote(reporter) +
                    ' reporter blew up with error:\n' +
                    err.stack
                );
          }
        } else {
          console.warn(
            sQuote(reporter) + ' reporter blew up with error:\n' + err.stack
          );
        }
      }
    }
    if (!_reporter) {
      throw createInvalidReporterError(
        'invalid reporter ' + sQuote(reporter),
        reporter
      );
    }
    this._reporter = _reporter;
  }
  this.options.reporterOptions = reporterOptions;
  return this;
};

/**
 * Sets test UI `name`, defaults to "bdd".
 *
 * @public
 * @see {@link https://mochajs.org/#-u---ui-name|CLI option}
 * @see {@link https://mochajs.org/#interfaces|Interface DSLs}
 * @param {string|Function} [ui=bdd] - Interface name or class.
 * @returns {Mocha} this
 * @chainable
 * @throws {Error} if requested interface cannot be loaded
 */
Mocha.prototype.ui = function(ui) {
  var bindInterface;
  if (typeof ui === 'function') {
    bindInterface = ui;
  } else {
    ui = ui || 'bdd';
    bindInterface = exports.interfaces[ui];
    if (!bindInterface) {
      try {
        bindInterface = require(ui);
      } catch (err) {
        throw createInvalidInterfaceError(
          'invalid interface ' + sQuote(ui),
          ui
        );
      }
    }
  }
  bindInterface(this.suite);

  this.suite.on(EVENT_FILE_PRE_REQUIRE, function(context) {
    exports.afterEach = context.afterEach || context.teardown;
    exports.after = context.after || context.suiteTeardown;
    exports.beforeEach = context.beforeEach || context.setup;
    exports.before = context.before || context.suiteSetup;
    exports.describe = context.describe || context.suite;
    exports.it = context.it || context.test;
    exports.xit = context.xit || (context.test && context.test.skip);
    exports.setup = context.setup || context.beforeEach;
    exports.suiteSetup = context.suiteSetup || context.before;
    exports.suiteTeardown = context.suiteTeardown || context.after;
    exports.suite = context.suite || context.describe;
    exports.teardown = context.teardown || context.afterEach;
    exports.test = context.test || context.it;
    exports.run = context.run;
  });

  return this;
};

/**
 * Loads `files` prior to execution.
 *
 * @description
 * The implementation relies on Node's `require` to execute
 * the test interface functions and will be subject to its cache.
 *
 * @private
 * @see {@link Mocha#addFile}
 * @see {@link Mocha#run}
 * @see {@link Mocha#unloadFiles}
 * @param {Function} [fn] - Callback invoked upon completion.
 */
Mocha.prototype.loadFiles = function(fn) {
  var self = this;
  var suite = this.suite;
  this.files.forEach(function(file) {
    file = path.resolve(file);
    suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);
    suite.emit(EVENT_FILE_REQUIRE, require(file), file, self);
    suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);
  });
  fn && fn();
};

/**
 * Removes a previously loaded file from Node's `require` cache.
 *
 * @private
 * @static
 * @see {@link Mocha#unloadFiles}
 * @param {string} file - Pathname of file to be unloaded.
 */
Mocha.unloadFile = function(file) {
  delete require.cache[require.resolve(file)];
};

/**
 * Unloads `files` from Node's `require` cache.
 *
 * @description
 * This allows files to be "freshly" reloaded, providing the ability
 * to reuse a Mocha instance programmatically.
 *
 * <strong>Intended for consumers &mdash; not used internally</strong>
 *
 * @public
 * @see {@link Mocha.unloadFile}
 * @see {@link Mocha#loadFiles}
 * @see {@link Mocha#run}
 * @returns {Mocha} this
 * @chainable
 */
Mocha.prototype.unloadFiles = function() {
  this.files.forEach(Mocha.unloadFile);
  return this;
};

/**
 * Sets `grep` filter after escaping RegExp special characters.
 *
 * @public
 * @see {@link Mocha#grep}
 * @param {string} str - Value to be converted to a regexp.
 * @returns {Mocha} this
 * @chainable
 * @example
 *
 * // Select tests whose full title begins with `"foo"` followed by a period
 * mocha.fgrep('foo.');
 */
Mocha.prototype.fgrep = function(str) {
  if (!str) {
    return this;
  }
  return this.grep(new RegExp(escapeRe(str)));
};

/**
 * @summary
 * Sets `grep` filter used to select specific tests for execution.
 *
 * @description
 * If `re` is a regexp-like string, it will be converted to regexp.
 * The regexp is tested against the full title of each test (i.e., the
 * name of the test preceded by titles of each its ancestral suites).
 * As such, using an <em>exact-match</em> fixed pattern against the
 * test name itself will not yield any matches.
 * <br>
 * <strong>Previous filter value will be overwritten on each call!</strong>
 *
 * @public
 * @see {@link https://mochajs.org/#-g---grep-pattern|CLI option}
 * @see {@link Mocha#fgrep}
 * @see {@link Mocha#invert}
 * @param {RegExp|String} re - Regular expression used to select tests.
 * @return {Mocha} this
 * @chainable
 * @example
 *
 * // Select tests whose full title contains `"match"`, ignoring case
 * mocha.grep(/match/i);
 * @example
 *
 * // Same as above but with regexp-like string argument
 * mocha.grep('/match/i');
 * @example
 *
 * // ## Anti-example
 * // Given embedded test `it('only-this-test')`...
 * mocha.grep('/^only-this-test$/');    // NO! Use `.only()` to do this!
 */
Mocha.prototype.grep = function(re) {
  if (utils.isString(re)) {
    // extract args if it's regex-like, i.e: [string, pattern, flag]
    var arg = re.match(/^\/(.*)\/(g|i|)$|.*/);
    this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);
  } else {
    this.options.grep = re;
  }
  return this;
};

/**
 * Inverts `grep` matches.
 *
 * @public
 * @see {@link Mocha#grep}
 * @return {Mocha} this
 * @chainable
 * @example
 *
 * // Select tests whose full title does *not* contain `"match"`, ignoring case
 * mocha.grep(/match/i).invert();
 */
Mocha.prototype.invert = function() {
  this.options.invert = true;
  return this;
};

/**
 * Enables or disables ignoring global leaks.
 *
 * @public
 * @see {@link Mocha#checkLeaks}
 * @param {boolean} ignoreLeaks - Whether to ignore global leaks.
 * @return {Mocha} this
 * @chainable
 * @example
 *
 * // Ignore global leaks
 * mocha.ignoreLeaks(true);
 */
Mocha.prototype.ignoreLeaks = function(ignoreLeaks) {
  this.options.ignoreLeaks = Boolean(ignoreLeaks);
  return this;
};

/**
 * Enables checking for global variables leaked while running tests.
 *
 * @public
 * @see {@link https://mochajs.org/#--check-leaks|CLI option}
 * @see {@link Mocha#ignoreLeaks}
 * @return {Mocha} this
 * @chainable
 */
Mocha.prototype.checkLeaks = function() {
  this.options.ignoreLeaks = false;
  return this;
};

/**
 * Displays full stack trace upon test failure.
 *
 * @public
 * @return {Mocha} this
 * @chainable
 */
Mocha.prototype.fullTrace = function() {
  this.options.fullStackTrace = true;
  return this;
};

/**
 * Enables desktop notification support if prerequisite software installed.
 *
 * @public
 * @see {@link Mocha#isGrowlCapable}
 * @see {@link Mocha#_growl}
 * @return {Mocha} this
 * @chainable
 */
Mocha.prototype.growl = function() {
  this.options.growl = this.isGrowlCapable();
  if (!this.options.growl) {
    var detail = process.browser
      ? 'notification support not available in this browser...'
      : 'notification support prerequisites not installed...';
    console.error(detail + ' cannot enable!');
  }
  return this;
};

/**
 * @summary
 * Determines if Growl support seems likely.
 *
 * @description
 * <strong>Not available when run in browser.</strong>
 *
 * @private
 * @see {@link Growl#isCapable}
 * @see {@link Mocha#growl}
 * @return {boolean} whether Growl support can be expected
 */
Mocha.prototype.isGrowlCapable = growl.isCapable;

/**
 * Implements desktop notifications using a pseudo-reporter.
 *
 * @private
 * @see {@link Mocha#growl}
 * @see {@link Growl#notify}
 * @param {Runner} runner - Runner instance.
 */
Mocha.prototype._growl = growl.notify;

/**
 * Specifies whitelist of variable names to be expected in global scope.
 *
 * @public
 * @see {@link https://mochajs.org/#-global-variable-name|CLI option}
 * @see {@link Mocha#checkLeaks}
 * @param {String[]|String} globals - Accepted global variable name(s).
 * @return {Mocha} this
 * @chainable
 * @example
 *
 * // Specify variables to be expected in global scope
 * mocha.globals(['jQuery', 'MyLib']);
 */
Mocha.prototype.globals = function(globals) {
  this.options.globals = this.options.globals
    .concat(globals)
    .filter(Boolean)
    .filter(function(elt, idx, arr) {
      return arr.indexOf(elt) === idx;
    });
  return this;
};

/**
 * Enables or disables TTY color output by screen-oriented reporters.
 *
 * @public
 * @param {boolean} colors - Whether to enable color output.
 * @return {Mocha} this
 * @chainable
 */
Mocha.prototype.useColors = function(colors) {
  if (colors !== undefined) {
    this.options.useColors = colors;
  }
  return this;
};

/**
 * Determines if reporter should use inline diffs (rather than +/-)
 * in test failure output.
 *
 * @public
 * @param {boolean} inlineDiffs - Whether to use inline diffs.
 * @return {Mocha} this
 * @chainable
 */
Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
  this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;
  return this;
};

/**
 * Determines if reporter should include diffs in test failure output.
 *
 * @public
 * @param {boolean} hideDiff - Whether to hide diffs.
 * @return {Mocha} this
 * @chainable
 */
Mocha.prototype.hideDiff = function(hideDiff) {
  this.options.hideDiff = hideDiff !== undefined && hideDiff;
  return this;
};

/**
 * @summary
 * Sets timeout threshold value.
 *
 * @description
 * A string argument can use shorthand (such as "2s") and will be converted.
 * If the value is `0`, timeouts will be disabled.
 *
 * @public
 * @see {@link https://mochajs.org/#-t---timeout-ms|CLI option}
 * @see {@link https://mochajs.org/#--no-timeouts|CLI option}
 * @see {@link https://mochajs.org/#timeouts|Timeouts}
 * @see {@link Mocha#enableTimeouts}
 * @param {number|string} msecs - Timeout threshold value.
 * @return {Mocha} this
 * @chainable
 * @example
 *
 * // Sets timeout to one second
 * mocha.timeout(1000);
 * @example
 *
 * // Same as above but using string argument
 * mocha.timeout('1s');
 */
Mocha.prototype.timeout = function(msecs) {
  this.suite.timeout(msecs);
  return this;
};

/**
 * Sets the number of times to retry failed tests.
 *
 * @public
 * @see {@link https://mochajs.org/#retry-tests|Retry Tests}
 * @param {number} retry - Number of times to retry failed tests.
 * @return {Mocha} this
 * @chainable
 * @example
 *
 * // Allow any failed test to retry one more time
 * mocha.retries(1);
 */
Mocha.prototype.retries = function(n) {
  this.suite.retries(n);
  return this;
};

/**
 * Sets slowness threshold value.
 *
 * @public
 * @see {@link https://mochajs.org/#-s---slow-ms|CLI option}
 * @param {number} msecs - Slowness threshold value.
 * @return {Mocha} this
 * @chainable
 * @example
 *
 * // Sets "slow" threshold to half a second
 * mocha.slow(500);
 * @example
 *
 * // Same as above but using string argument
 * mocha.slow('0.5s');
 */
Mocha.prototype.slow = function(msecs) {
  this.suite.slow(msecs);
  return this;
};

/**
 * Enables or disables timeouts.
 *
 * @public
 * @see {@link https://mochajs.org/#-t---timeout-ms|CLI option}
 * @see {@link https://mochajs.org/#--no-timeouts|CLI option}
 * @param {boolean} enableTimeouts - Whether to enable timeouts.
 * @return {Mocha} this
 * @chainable
 */
Mocha.prototype.enableTimeouts = function(enableTimeouts) {
  this.suite.enableTimeouts(
    arguments.length && enableTimeouts !== undefined ? enableTimeouts : true
  );
  return this;
};

/**
 * Forces all tests to either accept a `done` callback or return a promise.
 *
 * @public
 * @return {Mocha} this
 * @chainable
 */
Mocha.prototype.asyncOnly = function() {
  this.options.asyncOnly = true;
  return this;
};

/**
 * Disables syntax highlighting (in browser).
 *
 * @public
 * @return {Mocha} this
 * @chainable
 */
Mocha.prototype.noHighlighting = function() {
  this.options.noHighlighting = true;
  return this;
};

/**
 * Enables uncaught errors to propagate (in browser).
 *
 * @public
 * @return {Mocha} this
 * @chainable
 */
Mocha.prototype.allowUncaught = function() {
  this.options.allowUncaught = true;
  return this;
};

/**
 * @summary
 * Delays root suite execution.
 *
 * @description
 * Used to perform asynch operations before any suites are run.
 *
 * @public
 * @see {@link https://mochajs.org/#delayed-root-suite|delayed root suite}
 * @returns {Mocha} this
 * @chainable
 */
Mocha.prototype.delay = function delay() {
  this.options.delay = true;
  return this;
};

/**
 * Causes tests marked `only` to fail the suite.
 *
 * @public
 * @returns {Mocha} this
 * @chainable
 */
Mocha.prototype.forbidOnly = function() {
  this.options.forbidOnly = true;
  return this;
};

/**
 * Causes pending tests and tests marked `skip` to fail the suite.
 *
 * @public
 * @returns {Mocha} this
 * @chainable
 */
Mocha.prototype.forbidPending = function() {
  this.options.forbidPending = true;
  return this;
};

/**
 * Mocha version as specified by "package.json".
 *
 * @name Mocha#version
 * @type string
 * @readonly
 */
Object.defineProperty(Mocha.prototype, 'version', {
  value: require('../package.json').version,
  configurable: false,
  enumerable: true,
  writable: false
});

/**
 * Callback to be invoked when test execution is complete.
 *
 * @callback DoneCB
 * @param {number} failures - Number of failures that occurred.
 */

/**
 * Runs root suite and invokes `fn()` when complete.
 *
 * @description
 * To run tests multiple times (or to run tests in files that are
 * already in the `require` cache), make sure to clear them from
 * the cache first!
 *
 * @public
 * @see {@link Mocha#loadFiles}
 * @see {@link Mocha#unloadFiles}
 * @see {@link Runner#run}
 * @param {DoneCB} [fn] - Callback invoked when test execution completed.
 * @return {Runner} runner instance
 */
Mocha.prototype.run = function(fn) {
  if (this.files.length) {
    this.loadFiles();
  }
  var suite = this.suite;
  var options = this.options;
  options.files = this.files;
  var runner = new exports.Runner(suite, options.delay);
  createStatsCollector(runner);
  var reporter = new this._reporter(runner, options);
  runner.ignoreLeaks = options.ignoreLeaks !== false;
  runner.fullStackTrace = options.fullStackTrace;
  runner.asyncOnly = options.asyncOnly;
  runner.allowUncaught = options.allowUncaught;
  runner.forbidOnly = options.forbidOnly;
  runner.forbidPending = options.forbidPending;
  if (options.grep) {
    runner.grep(options.grep, options.invert);
  }
  if (options.globals) {
    runner.globals(options.globals);
  }
  if (options.growl) {
    this._growl(runner);
  }
  if (options.useColors !== undefined) {
    exports.reporters.Base.useColors = options.useColors;
  }
  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
  exports.reporters.Base.hideDiff = options.hideDiff;

  function done(failures) {
    fn = fn || utils.noop;
    if (reporter.done) {
      reporter.done(failures, fn);
    } else {
      fn(failures);
    }
  }

  return runner.run(done);
};
