'use strict';

/**
 * @typedef {import('../suite.js')} Suite
 */

var Test = require('../test');
var EVENT_FILE_PRE_REQUIRE =
  require('../suite').constants.EVENT_FILE_PRE_REQUIRE;

/**
 * TDD-style interface:
 *
 *      suite('Array', function() {
 *        suite('#indexOf()', function() {
 *          suiteSetup(function() {
 *
 *          });
 *
 *          test('should return -1 when not present', function() {
 *
 *          });
 *
 *          test('should return the index when present', function() {
 *
 *          });
 *
 *          suiteTeardown(function() {
 *
 *          });
 *        });
 *      });
 *
 * @param {Suite} suite Root suite.
 */
module.exports = function (suite) {
  var suites = [suite];

  suite.on(EVENT_FILE_PRE_REQUIRE, function (context, file, mocha) {
    var common = require('./common')(suites, context, mocha);

    context.setup = common.beforeEach;
    context.teardown = common.afterEach;
    context.suiteSetup = common.before;
    context.suiteTeardown = common.after;
    context.run = mocha.options.delay && common.runWithSuite(suite);

    /**
     * Describe a "suite" with the given `title` and callback `fn` containing
     * nested suites and/or tests.
     */
    context.suite = function (title, fn) {
      return common.suite.create({
        title,
        file,
        fn
      });
    };

    /**
     * Pending suite.
     */
    context.suite.skip = function (title, fn) {
      return common.suite.skip({
        title,
        file,
        fn
      });
    };

    /**
     * Exclusive test-case.
     */
    context.suite.only = function (title, fn) {
      return common.suite.only({
        title,
        file,
        fn
      });
    };

    /**
     * Describe a specification or test-case with the given `title` and
     * callback `fn` acting as a thunk.
     */
    context.test = function (title, fn) {
      var suite = suites[0];
      if (suite.isPending()) {
        fn = null;
      }
      var test = new Test(title, fn);
      test.file = file;
      suite.addTest(test);
      return test;
    };

    /**
     * Exclusive test-case.
     */

    context.test.only = function (title, fn) {
      return common.test.only(mocha, context.test(title, fn));
    };

    context.test.skip = common.test.skip;
  });
};

module.exports.description =
  'traditional "suite"/"test" instead of BDD\'s "describe"/"it"';
