"use strict";
var Promise = require('any-promise');
var FormData = require('form-data');
var arrify = require('arrify');
var querystring_1 = require('querystring');
var index_1 = require('./is-host/index');
var form_1 = require('../form');
var JSON_MIME_REGEXP = /^application\/(?:[\w!#\$%&\*`\-\.\^~]*\+)?json$/i;
var URL_ENCODED_MIME_REGEXP = /^application\/x-www-form-urlencoded$/i;
var FORM_MIME_REGEXP = /^multipart\/form-data$/i;
var JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/;
function wrap(value) {
    return function () { return value; };
}
exports.wrap = wrap;
exports.headers = wrap(function (request, next) {
    if (!request.get('Accept')) {
        request.set('Accept', '*/*');
    }
    request.remove('Host');
    return next();
});
exports.stringify = wrap(function (request, next) {
    var body = request.body;
    if (Object(body) !== body) {
        request.body = body == null ? null : String(body);
        return next();
    }
    if (index_1.default(body)) {
        return next();
    }
    var type = request.type();
    if (!type) {
        type = 'application/json';
        request.type(type);
    }
    try {
        if (JSON_MIME_REGEXP.test(type)) {
            request.body = JSON.stringify(body);
        }
        else if (FORM_MIME_REGEXP.test(type)) {
            request.body = form_1.default(body);
        }
        else if (URL_ENCODED_MIME_REGEXP.test(type)) {
            request.body = querystring_1.stringify(body);
        }
    }
    catch (err) {
        return Promise.reject(request.error('Unable to stringify request body: ' + err.message, 'ESTRINGIFY', err));
    }
    if (request.body instanceof FormData) {
        request.remove('Content-Type');
    }
    return next();
});
function parse(type, strict) {
    var types = arrify(type);
    for (var _i = 0, types_1 = types; _i < types_1.length; _i++) {
        var type_1 = types_1[_i];
        if (type_1 !== 'json' && type_1 !== 'urlencoded') {
            throw new TypeError("Unexpected parse type: " + type_1);
        }
    }
    return function (request, next) {
        return next()
            .then(function (response) {
            var body = response.body;
            var responseType = response.type();
            if (body == null || body === '') {
                response.body = null;
                return response;
            }
            if (responseType == null) {
                throw request.error("Unable to parse invalid response content type", 'EPARSE');
            }
            if (typeof body !== 'string') {
                throw request.error("Unable to parse non-string response body", 'EPARSE');
            }
            for (var _i = 0, types_2 = types; _i < types_2.length; _i++) {
                var type_2 = types_2[_i];
                if (type_2 === 'json' && JSON_MIME_REGEXP.test(responseType)) {
                    try {
                        response.body = JSON.parse(body.replace(JSON_PROTECTION_PREFIX, ''));
                    }
                    catch (err) {
                        throw request.error("Unable to parse response body: " + err.message, 'EPARSE', err);
                    }
                    return response;
                }
                if (type_2 === 'urlencoded' && URL_ENCODED_MIME_REGEXP.test(responseType)) {
                    response.body = querystring_1.parse(body);
                    return response;
                }
            }
            if (strict !== false) {
                throw request.error("Unhandled response type: " + responseType, 'EPARSE');
            }
            return response;
        });
    };
}
exports.parse = parse;
//# sourceMappingURL=common.js.map