"use strict";
/* eslint-disable @typescript-eslint/no-explicit-any */
Object.defineProperty(exports, "__esModule", { value: true });
exports.LogService = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@loopback/core");
const lodash_1 = require("lodash");
const models_1 = require("../../models");
const services_1 = require("../../services");
const transient_entity_service_1 = require("../../services/transient-entity/transient-entity.service");
const content_encrypted_object_definition_1 = require("../content-encrypted-object/content-encrypted-object.definition");
const server_config_service_1 = require("../server-config/server-config.service");
const log_const_1 = require("./log.const");
const DEFAULT_NB_LOGS = 1000;
const LOG_LEVEL = ['ERROR', 'WARNING', 'INFO', 'DEBUG'];
let LogService = class LogService {
    constructor(appCtx, transientEntityService, serverConfigService, objectNodeService, contentEncryptedObjectService) {
        this.appCtx = appCtx;
        this.transientEntityService = transientEntityService;
        this.serverConfigService = serverConfigService;
        this.objectNodeService = objectNodeService;
        this.contentEncryptedObjectService = contentEncryptedObjectService;
        this.transientEntityService.registerTransientEntityTypeFunction(log_const_1.LOG_PROVIDER, LogService.name, 'Add logs definition', models_1.EntityName.objectNode, log_const_1.LOGS_TYPE.name, this.completeLogsNode.bind(this));
        this.serverConfigService.registerNewConfigurationKey('debug', {
            type: 'boolean',
            title: 'Active debug mode',
        });
        this.serverConfigService.registerNewConfigurationKey('nbLogs', {
            type: 'number',
            title: 'Number of kept logs',
            default: DEFAULT_NB_LOGS,
        });
        this.serverConfigService.registerNewConfigurationKey('logLevel', {
            title: 'Log level',
            type: 'string',
            oneOf: LOG_LEVEL.map((level) => ({
                enum: [level],
                title: level,
            })),
        });
    }
    async completeLogsNode(objectNode, ctx) {
        var _a, _b, _c, _d, _e;
        if ((_e = (_d = (_c = (_b = (_a = objectNode.entityCtx) === null || _a === void 0 ? void 0 : _a.jsonSchema) === null || _b === void 0 ? void 0 : _b.properties) === null || _c === void 0 ? void 0 : _c.contentEncryptedObject) === null || _d === void 0 ? void 0 : _d.properties) === null || _e === void 0 ? void 0 : _e.value) {
            // objectNode.entityCtx.jsonSchema.properties.contentEncryptedObject.properties.value.properties = this.properties;
        }
    }
    async isDebug(level) {
        const debug = !!(await this.serverConfigService.getConfig()).debug;
        if (!debug)
            return false;
        let logLevel = (await this.serverConfigService.getConfig()).logLevel;
        if (!logLevel) {
            logLevel = 'INFO';
        }
        return LOG_LEVEL.indexOf(level) <= LOG_LEVEL.indexOf(logLevel);
    }
    addLogAsync(level, source, action, message, ctx, object) {
        this.addLog(level, source, action, message, ctx, object)
            .then(() => { })
            .catch(() => { });
    }
    async addLog(level, source, action, message, ctx, object) {
        if (!(await this.isDebug(level))) {
            return;
        }
        const logs = this.appCtx.getExtensionContext(log_const_1.LOG_PROVIDER).nodes.logs.value;
        if (!logs) {
            return;
        }
        const logsCtx = services_1.CurrentContext.get(ctx);
        const logsObj = await this.objectNodeService.getNode(logs.id, logsCtx);
        await this.contentEncryptedObjectService.addTransientContent(logsObj);
        if (!(logsObj === null || logsObj === void 0 ? void 0 : logsObj.contentEncryptedObject)) {
            logsObj.contentEncryptedObject = {};
        }
        if (!logsObj.contentEncryptedObject.value) {
            logsObj.contentEncryptedObject.value = {};
        }
        if (!logsObj.contentEncryptedObject.value.logs) {
            logsObj.contentEncryptedObject.value.logs = [];
        }
        const time = new Date().toISOString();
        logsObj.contentEncryptedObject.value.logs.unshift(`${time}  |  ${level}  |  ${source}  |  ${action}  |  ${message} ${object ? this.stringify(object) : ''}  |  memoryUsage: ${this.stringify(process.memoryUsage())}`);
        let nbLogs = (await this.serverConfigService.getConfig()).nbLogs;
        if (!nbLogs) {
            nbLogs = DEFAULT_NB_LOGS;
        }
        while (logsObj.contentEncryptedObject.value.logs.length > nbLogs) {
            logsObj.contentEncryptedObject.value.logs.pop();
        }
        await this.objectNodeService.modifyById(logsObj.id, logsObj, logsCtx, true);
        return;
    }
    stringify(obj) {
        if (lodash_1.isString(obj)) {
            return obj;
        }
        if (lodash_1.isBoolean(obj) || lodash_1.isNumber(obj)) {
            return JSON.stringify(obj);
        }
        if (lodash_1.isArray(obj)) {
            return ('[' +
                obj
                    .map((val) => {
                    return this.stringify(val);
                })
                    .join(',') +
                ']');
        }
        if (lodash_1.isObject(obj)) {
            return ('(' +
                Object.keys(obj)
                    .map((key) => {
                    return `${key} = ${this.stringify(obj[key])}`;
                })
                    .join(', ') +
                ')');
        }
        return JSON.stringify(obj);
    }
};
LogService = tslib_1.__decorate([
    tslib_1.__param(0, core_1.service(services_1.ApplicationService)),
    tslib_1.__param(1, core_1.service(transient_entity_service_1.TransientEntityService)),
    tslib_1.__param(2, core_1.service(server_config_service_1.ServerConfigService)),
    tslib_1.__param(3, core_1.service(services_1.ObjectNodeService)),
    tslib_1.__param(4, core_1.service(content_encrypted_object_definition_1.ContentEncryptedObjectService)),
    tslib_1.__metadata("design:paramtypes", [services_1.ApplicationService,
        transient_entity_service_1.TransientEntityService,
        server_config_service_1.ServerConfigService,
        services_1.ObjectNodeService,
        content_encrypted_object_definition_1.ContentEncryptedObjectService])
], LogService);
exports.LogService = LogService;
//# sourceMappingURL=log.service.js.map