'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

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

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck);
var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass);
var _assertThisInitialized__default = /*#__PURE__*/_interopDefaultLegacy(_assertThisInitialized);
var _get__default = /*#__PURE__*/_interopDefaultLegacy(_get);
var _inherits__default = /*#__PURE__*/_interopDefaultLegacy(_inherits);
var _possibleConstructorReturn__default = /*#__PURE__*/_interopDefaultLegacy(_possibleConstructorReturn);
var _getPrototypeOf__default = /*#__PURE__*/_interopDefaultLegacy(_getPrototypeOf);
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf__default['default'](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default['default'](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default['default'](this, result); }; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
var Response = /*#__PURE__*/function (_ServerResponse) {
  _inherits__default['default'](Response, _ServerResponse);

  var _super = _createSuper(Response);

  function Response(req) {
    var _this;

    _classCallCheck__default['default'](this, Response);

    _this = _super.call(this, req);

    _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "config", {});

    _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "request", {});

    _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "logger", {});

    _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "errorCallback", null);

    _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "startedAt", {});

    _defineProperty__default['default'](_assertThisInitialized__default['default'](_this), "endedAt", {});

    _this.request = req;
    return _this;
  }

  _createClass__default['default'](Response, [{
    key: "end",
    value:
    /**
     * 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
     */
    function end(data, encoding) {
      var _this2 = this;

      var resolvedData = data;

      if (!Buffer.isBuffer(data) && !utils.isString(data)) {
        if (utils.isObject(data)) {
          resolvedData = JSON.stringify(data);
        } else {
          resolvedData = '';
        }
      }

      return new Promise(function (resolve) {
        if (encoding) {
          _get__default['default'](_getPrototypeOf__default['default'](Response.prototype), "end", _this2).call(_this2, resolvedData, encoding, function () {
            resolve(true);
          });
        } else {
          _get__default['default'](_getPrototypeOf__default['default'](Response.prototype), "end", _this2).call(_this2, resolvedData, function () {
            resolve(true);
          });
        }
      });
    }
    /**
     * sets response header
     * @param name response header name
     * @param value response header value
     */

  }, {
    key: "setHeader",
    value: function setHeader(name, value) {
      _get__default['default'](_getPrototypeOf__default['default'](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__default['default'](_getPrototypeOf__default['default'](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.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
      });
    }
    /**
     * waits for the given time
     */

  }, {
    key: "wait",
    value: function wait(time) {
      var _this5 = this;

      return new Promise(function (resolve) {
        setTimeout(function () {
          resolve(_this5);
        }, time);
      });
    }
  }]);

  return Response;
}(http.ServerResponse);

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