'use strict';

var request = require('request'),
    Bluebird = require('bluebird'),
    _ = require('lodash');


function ownCallback(err, httpResponse, body) {

    /* jshint validthis:true */
    var self = this;

    if (_.isFunction(self._rp_callbackOrig)) {
        try {
            self._rp_callbackOrig.apply(self, arguments);
        } catch (e) { }
    }

    if (err) {
        self._rp_reject({
            error: err,
            options: self._rp_options,
            response: httpResponse
        });
    } else if (self._rp_options.simple && !(/^2/.test('' + httpResponse.statusCode))) {
        self._rp_reject({
            error: body,
            options: self._rp_options,
            response: httpResponse,
            statusCode: httpResponse.statusCode
        });
    } else {
        if (_.isFunction(self._rp_options.transform)) {
            try {
                self._rp_resolve(self._rp_options.transform(body, httpResponse));
            } catch (e) {
                self._rp_reject(e);
            }
        } else if (self._rp_options.resolveWithFullResponse) {
            self._rp_resolve(httpResponse);
        } else {
            self._rp_resolve(body);
        }
    }

}

var originalInit = request.Request.prototype.init;

request.Request.prototype.init = function (options) {

    var self = this;

    self._rp_promise = new Bluebird(function (resolve, reject) {

        self._rp_resolve = resolve;
        self._rp_reject = reject;

    });

    self._rp_callbackOrig = self.callback;
    self.callback = ownCallback;

    if (_.isPlainObject(options)) {

        if (_.isString(options.method)) {
            options.method = options.method.toUpperCase();
        }

        self._rp_options = options;
        self._rp_options.simple = options.simple === false ? false : true;
        self._rp_options.resolveWithFullResponse = options.resolveWithFullResponse === true ? true : false;

    } else {

        self._rp_options = {
            simple: true,
            resolveWithFullResponse: false
        };

    }

    return originalInit.apply(self, arguments);

};

request.Request.prototype.then = function (onFulfilled, onRejected) {
    return this._rp_promise.then(onFulfilled, onRejected);
};

module.exports = request;

@@ -1335,24 +1335,196 @@
 lf = this;%0A%0A
+    // Init may be called again - currently in case of redirects%0A    if (_.isPlainObject(options) && self._callback === undefined && self._rp_promise === undefined) %7B%0A%0A    
     self._rp
@@ -1572,25 +1572,28 @@
 , reject) %7B%0A
-%0A
+    
         self
@@ -1616,32 +1616,36 @@
 esolve;%0A        
+ 
+   
 self._rp_reject 
@@ -1658,18 +1658,25 @@
 ct;%0A
-%0A
+   
     
+ 
 %7D);%0A%0A
+    
     
@@ -1714,24 +1714,28 @@
 llback;%0A    
+  
+  
 self.callbac
@@ -1756,45 +1756,8 @@
 k;%0A%0A
-    if (_.isPlainObject(options)) %7B%0A%0A
     
@@ -2088,132 +2088,8 @@
 e;%0A%0A
-    %7D else %7B%0A%0A        self._rp_options = %7B%0A            simple: true,%0A            resolveWithFullResponse: false%0A        %7D;%0A%0A
     

Fix for init calls after redirects