"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const requestHandler_1 = require("./requestHandler");
const http_1 = require("http");
const Errors = require("./errors");
const SECONDS_IN_ONE_DAY = 86400;
let self;
class ApiServer {
    constructor(options) {
        this.middleware = [];
        this.options = options;
        self = this;
    }
    setHeaders(res) {
        let cors = this.options.cors;
        res.setHeader('Access-Control-Allow-Origin', cors.origin || '*');
        res.setHeader('Access-Control-Max-Age', cors.maxAge.toString() || SECONDS_IN_ONE_DAY.toString());
        res.setHeader('Access-Control-Allow-Credentials', (cors.credentials || false) === true ? 'true' : 'false');
        res.removeHeader('X-Powered-By');
        res.setHeader('Server', this.options.serverName || 'APIserver');
        if (this.options.enableSecurityHeaders) {
            const headers = {
                "X-Content-Type-Options": "nosniff",
                "X-Frame-Options": "SAMEORIGIN",
                "X-Xss-Protection": "1; mode=block"
            };
            for (let i in headers) {
                res.setHeader(i, headers[i]);
            }
        }
    }
    responseFunctions(response) {
        response.status = (code) => {
            response.statusCode = code;
        };
        response.send = (data, status = 200) => {
            let responseData = {
                content: data,
                contentType: 'text/plain; charset=utf-8'
            };
            if (typeof data === 'object') {
                responseData.contentType = 'application/json; charset=utf-8';
                if (data instanceof Errors.ApiError) {
                    response.writeHead(data.status, {
                        'Content-Type': responseData.contentType
                    });
                    response.write(this.responseWithError(data));
                    response.end();
                    return;
                }
                responseData.content = JSON.stringify(data);
            }
            response.writeHead(status, {
                'Content-Type': responseData.contentType
            });
            response.write(responseData.content);
            response.end();
        };
    }
    responseWithError(error) {
        return JSON.stringify({
            code: error.status,
            message: error.message,
            description: error.description
        });
    }
    handler(request, response) {
        request.params = {};
        request.body = {};
        self.setHeaders(response);
        self.responseFunctions(response);
        return requestHandler_1.RequestHandler.handle(self, request, response);
    }
    register(routes) {
        this.routes = routes;
    }
    use(middleware) {
        this.middleware.push(middleware);
    }
    run() {
        this.server = http_1.createServer(this.handler);
        this.server.listen(this.options.port, this.options.hostname || 'localhost');
    }
}
exports.ApiServer = ApiServer;
