'use strict';

module.exports = (chai, utils) => {

  require('./lib/status-methods')(method);
  require('./lib/body-methods')(method);
  require('./lib/header-methods')(method);

  function method(options) {
    utils.addMethod(chai.Assertion.prototype, options.name, function () {
      var result = {};
      var args = arguments;
      var that = this;
      var derivedPromise = this._obj.then(res => {
        result.res = res;
        return result;
      });

      if(options.isBodyMatcher){
        derivedPromise = derivedPromise.then(result => {
          return result.res.text();
        }).then(text => {
          result.text = text;
          return result;
        });
      }

      derivedPromise = derivedPromise.then(result => {
        this.assert(
          options.predicate(result.res, result.text, args),
          options.msgSuccess(args),
          options.msgFail(args),
          options.expected(args),
          options.actual(result.res, result.text)
        );
      });
      // credit to chai-as-promised
      transferPromiseness(that, derivedPromise);
    });
  }

  function transferPromiseness(assertion, promise) {
    assertion.then = promise.then.bind(promise);
  }

};



@@ -381,101 +381,205 @@
 e = 
-this._obj.then(res =%3E %7B%0A        result.res = res;%0A        return
+fetchResult(this._obj, result);%0A      derivedPromise = enrichBodyIfBodyMatcher(derivedPromise,%0A                                              
  result
-;
+,
 %0A      
-%7D);%0A%0A
+                                   
       
-if(
 opti
@@ -600,69 +600,438 @@
 her)
-%7B
+;
 %0A      
-  derivedPromise = derivedPromise.then(result =%3E %7B%0A  
+derivedPromise = assert(derivedPromise, options, that, args);%0A%0A      // credit to chai-as-promised%0A      transferPromiseness(that, derivedPromise);%0A    %7D);%0A  %7D%0A%0A  function fetchResult(promise, result) %7B%0A    return promise.then(res =%3E %7B%0A      result.res = res;%0A      return result;%0A    %7D);%0A  %7D%0A%0A  function enrichBodyIfBodyMatcher(promise, result, conditation) %7B%0A    if (conditation) %7B%0A      return promise.then(result =%3E %7B%0A
     
@@ -1066,18 +1066,16 @@
 ;%0A      
- 
- 
 %7D).then(
@@ -1080,26 +1080,24 @@
 n(text =%3E %7B%0A
-  
         resu
@@ -1116,26 +1116,24 @@
 xt;%0A        
-  
 return resul
@@ -1141,26 +1141,24 @@
 ;%0A      
- 
- 
 %7D);%0A    
   %7D%0A%0A   
@@ -1153,44 +1153,111 @@
     
-  %7D%0A%0A      derivedPromise = derivedP
+%7D else %7B%0A      return promise;%0A    %7D%0A  %7D%0A%0A  function assert(promise, options, that, args)%7B%0A    return p
 romi
@@ -1286,14 +1286,12 @@
     
-  this
+that
 .ass
@@ -1295,34 +1295,32 @@
 assert(%0A        
- 
- 
 options.predicat
@@ -1349,26 +1349,24 @@
 ext, args),%0A
-  
         opti
@@ -1387,34 +1387,32 @@
 (args),%0A        
-  
 options.msgFail(
@@ -1418,34 +1418,32 @@
 (args),%0A        
- 
- 
 options.expected
@@ -1446,26 +1446,24 @@
 cted(args),%0A
-  
         opti
@@ -1508,115 +1508,17 @@
     
-  
 );%0A    
- 
- 
 %7D)
-;%0A      // credit to chai-as-promised%0A      transferPromiseness(that, derivedPromise);%0A    %7D);
 %0A  %7D

make main function nicer