var assert        = require("assert");
var util          = require("util");
var http          = require("http");
var https         = require("https");
var url           = require("url");
var addressparser = require("addressparser");
var pkg           = require("../package.json");

//
// Constants
//
var STATUS_OK = 200;

//
// Helper
//
function isString(v) {
    return typeof v === "string" || v instanceof String;
}

function checkOptions(options) {
    var apiKey = options.apiKey;
    var apiUrl = options.apiUrl;

    assert(apiKey && isString(apiKey), "apiKey: must be a non-empty string");
    assert(apiUrl && isString(apiUrl), "apiUrl: must be a non-empty string");
}

function addAddress(obj, address) {
    obj[address.address] = address.name || "";
    return obj;
}

function flattenGroups(addresses) {
    var flattened = [];

    function traverse(obj) {
        if (obj.group) {
            obj.group.forEach(traverse);
        } else {
            flattened.push(obj);
        }
    }

    addresses.forEach(traverse);

    return flattened;
}

function transformAddresses(addresses) {
    return flattenGroups(addressparser(addresses)).reduce(function (obj, address) {
        return addAddress(obj, address);
    }, {});
}

function transformFromAddresses(addresses) {
    var fromAddress = flattenGroups(addressparser(addresses))[0];

    return [fromAddress.address, fromAddress.name];
}

function isErrorResponse(response) {
    if (response.statusCode !== STATUS_OK) {
        return true;
    }

    return false;
}

function responseError(response, body) {
    return new Error(
        util.format("%s (%s, %d)",
            body.message || "server error",
            body.code || "-",
            response.statusCode));
}

function makeInfo(data) {
    return {
        messageId: data["message-id"] || ""
    };
}

//
// Transport class
//
function SendinBlueTransport(options) {
    checkOptions(options);

    this.name    = "SendinBlue";
    this.version = pkg.version;

    this.key = options.apiKey;
    this.endPoint = url.parse(options.apiUrl + "/email");
    this.reqBuilder = http.request;

    if (this.endPoint.protocol === "https:") {
        this.reqBuilder = https.request;
    }
}

SendinBlueTransport.prototype.send = function (mail, callback) {
    var req = this.reqBuilder({
        method: "POST",
        headers: {
            "api-key": this.key,
            "Content-Type": "application/json"
        },
        protocol: this.endPoint.protocol,
        host: this.endPoint.host,
        port: this.endPoint.port,
        path: this.endPoint.path
    }, function (res) {
        res.setEncoding("utf-8");

        var data = "";
        res.on("data", function (chunk) {
            data += chunk;
        });

        res.on("end", function () {
            var body = {};

            try {
                body = JSON.parse(data);
            } catch (err) { /* Ignore error */ }

            if (isErrorResponse(res)) {
                return callback(responseError(res, body));
            }

            callback(null, makeInfo(body.data));
        });
    });

    req.write(JSON.stringify(this.transformData(mail.data)));
    req.end();
};

SendinBlueTransport.prototype.transformData = function (data) {
    return {
        from:    transformFromAddresses(data.from),
        to:      transformAddresses(data.to),
        cc:      transformAddresses(data.cc),
        bcc:     transformAddresses(data.bcc),
        replyto: transformFromAddresses(data.replyTo),
        subject: data.subject,
        text:    data.text,
        html:    data.html
    };
};

module.exports = function (options) {
    return new SendinBlueTransport(options);
};

@@ -2012,47 +2012,18 @@
 his.
-key = options.apiKey;%0A    this.endPoint
+reqOptions
  = u
@@ -2075,274 +2075,65 @@
 .req
-Builder = http.request;%0A%0A    if (this.endPoint.protocol === %22https:%22) %7B%0A        this.reqBuilder = https.request;%0A    %7D%0A%7D%0A%0ASendinBlueTransport.prototype.send = function (mail, callback) %7B%0A    var req = this.reqBuilder(%7B%0A        method: %22POST%22,%0A        
+Options.method = %22POST%22;%0A    this.reqOptions.
 headers
-:
+ =
  %7B%0A
-    
     
@@ -2151,22 +2151,24 @@
 y%22: 
-this.key,%0A    
+options.apiKey,%0A
     
@@ -2214,163 +2214,222 @@
     
-    %7D,
+%7D; 
 %0A    
+%0A
     
-protocol: this.endPoint.protocol,%0A        ho
+this.reqBuilder = this.reqOptions.protocol === %22https:%22 ? https.reque
 st
+ 
 : 
-this.endPoint.host,%0A        port: this.endPoint.port,%0A        path: this.endPoint.path%0A    %7D
+http.request;%0A%7D%0A%0ASendinBlueTransport.prototype.send = function (mail, callback) %7B%0A    var req = this.reqBuilder(this.reqOptions
 , fu

Build request options only once