module.exports = makeRequest;

var debug = require('debug')('snyk:req');
var Promise = require('es6-promise').Promise; // jshint ignore:line
var request = require('request');
var stream = require('stream');
var parse = require('url').parse;
var format = require('url').format;
var zlib = require('zlib');
var config = require('../config');

function makeRequest(payload) {
  return new Promise(function (resolve, reject) {
    var body = payload.body;
    var bodyStream;

    delete payload.body;

    if (body) {
      // always compress going upstream
      bodyStream = new stream.Readable();
      var json = JSON.stringify(body);
      bodyStream.push(json);
      bodyStream.push(null);

      debug('compressing body (%s)', json.length);
      if (json.length < 1e4) {
        debug(JSON.stringify(body, '', 2));
      }

      if (!payload.headers) {
        payload.headers = {};
      }

      payload.headers['content-encoding'] = 'gzip';
    }

    var url = parse(payload.url);

    if (url.protocol === 'http:' && url.hostname !== 'localhost') {
      debug('forcing api request to https');
      url.protocol = 'https:';
      payload.url = format(url);
    }

    // prefer config timeout unless payload specified
    if (!payload.hasOwnProperty('timeout')) {
      payload.timeout = config.timeout * 1000; // s -> ms
    }

    debug('request payload: ', JSON.stringify(payload));
    var req = request(payload, function (error, res, body) {
      debug(error);
      debug('response (%s): ', (res || {}).statusCode, JSON.stringify(body));
      if (error) {
        return reject(error);
      }

      resolve({ res: res, body: body });
    });

    if (body) {
      bodyStream.pipe(zlib.createGzip()).pipe(req);
    }
  });
}
