"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CustomHttpKernel = void 0;
function __assignType(fn, args) {
    fn.__type = args;
    return fn;
}
const http_1 = require("@deepkit/http");
/*@ts-ignore*/
var { __ΩLoggerInterface } = require('@deepkit/logger');
const resolver_1 = require("../app/resolver");
const helpers_1 = require("../helpers");
const services_1 = require("../services");
const context_1 = require("./context");
const __ΩRequestLogger = [() => __ΩLoggerInterface, 'logger', () => http_1.HttpRequest, 'request', '', 'start', () => __ΩLoggerInterface, () => http_1.HttpRequest, () => http_1.HttpResponse, 'response', 'finish', () => __ΩLoggerInterface, () => http_1.HttpRequest, 'abort', 'RequestLogger', 'PPn!2"P7#2$$/%4&8Pn\'2"P7(2$P7)2*$/%4+8Pn,2"P7-2$$/%4.8Mw/y'];
class CustomHttpKernel extends http_1.HttpKernel {
    constructor() {
        super(...arguments);
        this.activeRequestCount = 0;
        this.scopedLogger = (0, services_1.createLogger)('http');
    }
    shouldSkipRequestLogging(request) {
        return request.url === '/healthz' || request.url === '/metrics';
    }
    buildRequestLogger() {
        const logMode = (0, resolver_1.getAppConfig)().HTTP_REQUEST_LOGGING_MODE;
        const abortFn = __assignType((logger, request) => {
            logger.warn('Request aborted during processing', {
                method: request.method,
                url: request.url,
                duration: Date.now() - request.store['$RequestTime']
            });
        }, ['logger', 'request', '', 'P"2!"2""/#']);
        const finishFn = __assignType((logger, request, response) => {
            const msg = response.statusCode >= 400 ? 'Request failed' : response.writableEnded ? 'Request completed' : 'Response stream hooked by controller';
            logger.info(msg, {
                method: request.method,
                url: request.url,
                statusCode: response.statusCode,
                duration: Date.now() - request.store['$RequestTime']
            });
        }, ['logger', 'request', 'response', '', 'P"2!"2""2#"/$']);
        if (logMode === 'e2e') {
            return {
                start: __assignType((logger, request) => {
                    request.store['$RequestTime'] = Date.now();
                    if (!this.shouldSkipRequestLogging(request)) {
                        logger.info('Request started', {
                            method: request.method,
                            url: request.url,
                            remoteAddress: request.getRemoteAddress(),
                            contentLength: request.headers['content-length']
                        });
                    }
                }, ['logger', 'request', '', 'P"2!"2""/#']),
                finish: __assignType((logger, request, response) => {
                    if (response.statusCode >= 400 || !this.shouldSkipRequestLogging(request)) {
                        finishFn(logger, request, response);
                    }
                }, ['logger', 'request', 'response', '', 'P"2!"2""2#"/$']),
                abort: abortFn
            };
        }
        if (logMode === 'finish') {
            return {
                start: __assignType((_logger, request) => {
                    request.store['$RequestTime'] = Date.now();
                }, ['_logger', 'request', '', 'P"2!"2""/#']),
                finish: __assignType((logger, request, response) => {
                    if (response.statusCode >= 400 || !this.shouldSkipRequestLogging(request)) {
                        finishFn(logger, request, response);
                    }
                }, ['logger', 'request', 'response', '', 'P"2!"2""2#"/$'])
            };
        }
        if (logMode === 'errors') {
            return {
                start: __assignType((_logger, request) => {
                    request.store['$RequestTime'] = Date.now();
                }, ['_logger', 'request', '', 'P"2!"2""/#']),
                finish: __assignType((logger, request, response) => {
                    if (response.statusCode >= 400) {
                        finishFn(logger, request, response);
                    }
                }, ['logger', 'request', 'response', '', 'P"2!"2""2#"/$']),
                abort: abortFn
            };
        }
        return {
            start: __assignType((_logger, request) => {
                request.store['$RequestTime'] = Date.now();
            }, ['_logger', 'request', '', 'P"2!"2""/#']),
            abort: abortFn
        };
    }
    get requestLogger() {
        const logger = this.buildRequestLogger();
        Object.defineProperty(this, 'requestLogger', { value: logger });
        return logger;
    }
    async handleRequest(req, res) {
        try {
            this.activeRequestCount++;
            const httpCtx = (0, context_1.getHttpContextResolver)()(req);
            await (0, helpers_1.withContextData)({ http: httpCtx }, async () => {
                this.requestLogger.start?.(this.scopedLogger, req);
                await (Promise.Ω = [['$']], new Promise(__assignType((resolve, reject) => {
                    const onClose = () => {
                        if (res.destroyed && !res.writableFinished) {
                            this.requestLogger.abort?.(this.scopedLogger, req);
                            resolve();
                        }
                    };
                    res.on('close', onClose);
                    super
                        .handleRequest(req, res)
                        .then(() => {
                        res.removeListener('close', onClose);
                        this.requestLogger.finish?.(this.scopedLogger, req, res);
                        resolve();
                    })
                        .catch(reject);
                }, ['resolve', 'reject', '', 'P"2!"2""/#'])));
            });
        }
        finally {
            this.activeRequestCount--;
        }
    }
}
exports.CustomHttpKernel = CustomHttpKernel;
CustomHttpKernel.__type = [() => http_1.HttpKernel, 'activeRequestCount', function () { return 0; }, 'scopedLogger', function () { return (0, services_1.createLogger)('http'); }, () => http_1.HttpRequest, 'request', 'shouldSkipRequestLogging', () => __ΩRequestLogger, 'buildRequestLogger', () => http_1.HttpRequest, 'req', () => http_1.HttpResponse, 'res', 'handleRequest', 'CustomHttpKernel', 'P7!\'3";>#!3$;>%PP7&2\'"0(;Pn)0*;!PP7+2,P7-2.$`0/5w0'];
//# sourceMappingURL=kernel.js.map