'use strict';

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var _classCallCheck = _interopDefault(require('@babel/runtime/helpers/classCallCheck'));
var _createClass = _interopDefault(require('@babel/runtime/helpers/createClass'));
var _possibleConstructorReturn = _interopDefault(require('@babel/runtime/helpers/possibleConstructorReturn'));
var _assertThisInitialized = _interopDefault(require('@babel/runtime/helpers/assertThisInitialized'));
var _getPrototypeOf = _interopDefault(require('@babel/runtime/helpers/getPrototypeOf'));
var _get = _interopDefault(require('@babel/runtime/helpers/get'));
var _inherits = _interopDefault(require('@babel/runtime/helpers/inherits'));
var _defineProperty = _interopDefault(require('@babel/runtime/helpers/defineProperty'));
var http = require('http');
var utils = require('@forensic-js/utils');
var FileServer = _interopDefault(require('./FileServer'));

var Response =
/*#__PURE__*/
function (_ServerResponse) {
  _inherits(Response, _ServerResponse);

  function Response(req) {
    var _this;

    _classCallCheck(this, Response);

    _this = _possibleConstructorReturn(this, _getPrototypeOf(Response).call(this, req));

    _defineProperty(_assertThisInitialized(_this), "config", {});

    _defineProperty(_assertThisInitialized(_this), "request", {});

    _defineProperty(_assertThisInitialized(_this), "logger", {});

    _defineProperty(_assertThisInitialized(_this), "errorCallback", null);

    _defineProperty(_assertThisInitialized(_this), "startedAt", {});

    _defineProperty(_assertThisInitialized(_this), "endedAt", {});

    _this.request = req;
    return _this;
  }

  _createClass(Response, [{
    key: "end",

    /**
     * ends the response with optional response data, and optional data encoding
     * @param data optional data to send. either string or buffer
     * @param encoding data encoding if not buffer
     */
    value: function end(data, encoding) {
      var _this2 = this;

      return new Promise(function (resolve) {
        if (encoding) {
          _get(_getPrototypeOf(Response.prototype), "end", _this2).call(_this2, data, encoding, function () {
            resolve(true);
          });
        } else {
          _get(_getPrototypeOf(Response.prototype), "end", _this2).call(_this2, data, function () {
            resolve(true);
          });
        }
      });
    }
    /**
     * sets response header
     * @param name response header name
     * @param value response header value
     */

  }, {
    key: "setHeader",
    value: function setHeader(name, value) {
      _get(_getPrototypeOf(Response.prototype), "setHeader", this).call(this, name, value);

      return this;
    }
    /**
     * sets multiple response headers
     * @param headers object containing response header name value pairs
     */

  }, {
    key: "setHeaders",
    value: function setHeaders(headers) {
      var _this3 = this;

      Object.keys(headers).forEach(function (key) {
        _this3.setHeader(key, headers[key]);
      });
      return this;
    }
    /**
     * removes a single set response header at a time. function is chainable
     * @param name response header to remove
     */

  }, {
    key: "removeHeader",
    value: function removeHeader(name) {
      _get(_getPrototypeOf(Response.prototype), "removeHeader", this).call(this, name);

      return this;
    }
    /**
     * remove response headers that are already set. function is chainable
     * @param names - comma separated list of header names to remove
     */

  }, {
    key: "removeHeaders",
    value: function removeHeaders() {
      var _this4 = this;

      for (var _len = arguments.length, names = new Array(_len), _key = 0; _key < _len; _key++) {
        names[_key] = arguments[_key];
      }

      names.forEach(function (name) {
        _this4.removeHeader(name);
      });
      return this;
    }
    /**
     * sets response status code
     * @param code - the response code
     */

  }, {
    key: "status",
    value: function status(code) {
      this.statusCode = code;
      return this;
    }
    /**
     * sends json response back to the client.
     * @param data - the json string or json object which will be stringified
     */

  }, {
    key: "json",
    value: function json(data) {
      if (!utils.isString(data)) {
        data = JSON.stringify(data);
      }

      return this.setHeader('Content-Type', 'application/json').end(data);
    }
    /**
     * Redirect client to the given url
     */

  }, {
    key: "redirect",
    value: function redirect(path) {
      var status = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 302;
      return this.status(status).setHeader('Location', path).end();
    }
    /**
     * sends a file download attachment to the client
     * @param filePath - relative or absolute file path
     * @param filename - suggested file download name
     */

  }, {
    key: "download",
    value: function download(filePath, filename) {
      var fileServer = new FileServer(this.config, this.logger, this.request, this, this.errorCallback);
      return fileServer.serveDownload(filePath, filename);
    }
    /**
     * sends json error data back to the client
     * @param statusCode http error status code, defaults to 400
     * @param message short message to return to client
     * @param errorData error data object, defaults to empty object
     */

  }, {
    key: "jsonError",
    value: function jsonError() {
      var statusCode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 400;
      var message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'request failed';
      var errors = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
      return this.status(statusCode).json({
        status: 'error',
        code: statusCode,
        message: message,
        errors: errors
      });
    }
    /**
     * sends json success data back to the client
     * @param statusCode http status code, defaults to 200
     * @param message short message to return to client
     * @param successData success data object, default to empty object
     */

  }, {
    key: "jsonSuccess",
    value: function jsonSuccess() {
      var statusCode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 200;
      var message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'request successful';
      var data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
      return this.status(statusCode).json({
        status: 'success',
        code: statusCode,
        message: message,
        data: data
      });
    }
  }]);

  return Response;
}(http.ServerResponse);

module.exports = Response;
//# sourceMappingURL=Response.js.map
