'use strict';

/**
 * Module dependencies.
 */

var JSON = require('json3');

/**
 * Expose `Context`.
 */

module.exports = Context;

/**
 * Initialize a new `Context`.
 *
 * @api private
 */
function Context () {}

/**
 * Set or get the context `Runnable` to `runnable`.
 *
 * @api private
 * @param {Runnable} runnable
 * @return {Context}
 */
Context.prototype.runnable = function (runnable) {
  if (!arguments.length) {
    return this._runnable;
  }
  this.test = this._runnable = runnable;
  return this;
};

/**
 * Set test timeout `ms`.
 *
 * @api private
 * @param {number} ms
 * @return {Context} self
 */
Context.prototype.timeout = function (ms) {
  if (!arguments.length) {
    return this.runnable().timeout();
  }
  this.runnable().timeout(ms);
  return this;
};

/**
 * Set test timeout `enabled`.
 *
 * @api private
 * @param {boolean} enabled
 * @return {Context} self
 */
Context.prototype.enableTimeouts = function (enabled) {
  this.runnable().enableTimeouts(enabled);
  return this;
};

/**
 * Set test slowness threshold `ms`.
 *
 * @api private
 * @param {number} ms
 * @return {Context} self
 */
Context.prototype.slow = function (ms) {
  this.runnable().slow(ms);
  return this;
};

/**
 * Mark a test as skipped.
 *
 * @api private
 * @return {Context} self
 */
Context.prototype.skip = function () {
  this.runnable().skip();
  return this;
};

/**
 * Allow a number of retries on failed tests
 *
 * @api private
 * @param {number} n
 * @return {Context} self
 */
Context.prototype.retries = function (n) {
  if (!arguments.length) {
    return this.runnable().retries();
  }
  this.runnable().retries(n);
  return this;
};

/**
 * Inspect the context void of `._runnable`.
 *
 * @api private
 * @return {string}
 */
Context.prototype.inspect = function () {
  return JSON.stringify(this, function (key, val) {
    return key === 'runnable' || key === 'test' ? undefined : val;
  }, 2);
};
