/**
 * @module
 */
import _ from 'lodash';
import {pint} from './types/number';
import {elements} from './combinators';

/**
 * Something to do monkey testing.
 */
class ChaosMonkey {
  constructor(opts = {}) {
    this._seed = opts.seed || pint.generate();
    this.actions = {};
    this._preconds = {};
    this._postconds = {};
    this._speed = opts.speed || 50;
    this._locale = 'en';
  }
  /**
   * Add a behaviour.
   *
   * @param {string} name
   * @param {Arbitrary} action
   */
  behaviour(name, action, opts = {}) {
    this.actions[name] = action;
    this._preconds[name] = opts.precond || _.noop;
    this._postconds[name] = opts.postcond || _.noop;
  }
  /**
   * Do random behaviour.
   */
  doRandomBehaviour() {
    let randomActName = elements(Object.keys(this.actions))
          .seed(this._seed)
          .generate();
    let precond = this._preconds[randomActName];
    let postcond = this._postconds[randomActName];
    let randomAction = this.actions[randomActName]
                         .locale(this._locale)
                         .seed(this._seed);

    precond(this, randomActName); // check pre conditin.
    randomAction.promise()        // do the action.
      .then(postcond)             // check post condition.
      .catch(console.error);
  }
  /**
   * Replay monkey testing by given seed.
   *
   * @return {number} seed 32-bit integer.
   */
  replay(seed) {
    this._seed = seed;
    this.start();
  }
  /**
   * Start running monkey testing.
   *
   * @return {number} interval id.
   */
  start() {
    console.log(`seed: ${this._seed}`);
    let task = () => this.doRandomBehaviour();
    return this.timeId = setInterval(task, this._speed);
  }
  /**
   * Stop running monkey testing.
   */
  stop() {
    clearInterval(this.timeId);
  }
}

export {
  ChaosMonkey
};

@@ -386,16 +386,98 @@
 = 'en';%0A
+    this._preDo = opts.preDo %7C%7C _.noop;%0A    this._postDo = opts.postDo %7C%7C _.noop;%0A
   %7D%0A  /*
@@ -1167,138 +1167,202 @@
 d);%0A
-%0A    precond(this, randomActName); // check
+    // hook helpers%0A    let preDo = () =%3E %7B%0A      this._preDo.apply(this);%0A     
  pre
- 
 cond
-itin.%0A    randomAction.promise()        // do the action.
+.apply(this);%0A    %7D;%0A%0A    let postDo = (...args) =%3E %7B%0A      this._postDo.apply(this, args);
 %0A      
-.then(
 postcond
 )   
@@ -1361,46 +1361,95 @@
 cond
-)             // check post condition.
+.apply(this, args);%0A    %7D;%0A%0A    preDo();%0A    randomAction.promise()%0A      .then(postDo)
 %0A   

Add preDo and postDo hook to ChaosMonkey class.