"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.logger = void 0;
exports.setContext = setContext;
exports.getContext = getContext;
exports.setMeta = setMeta;
exports.addMeta = addMeta;
exports.removeMeta = removeMeta;
exports.addStream = addStream;
exports.levels = levels;
exports.getProblems = getProblems;
exports.clearProblems = clearProblems;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const bunyan = tslib_1.__importStar(require("bunyan"));
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
const nanoid_1 = require("nanoid");
const upath_1 = tslib_1.__importDefault(require("upath"));
const cmd_serializer_1 = tslib_1.__importDefault(require("./cmd-serializer"));
const config_serializer_1 = tslib_1.__importDefault(require("./config-serializer"));
const err_serializer_1 = tslib_1.__importDefault(require("./err-serializer"));
const once_1 = require("./once");
const pretty_stdout_1 = require("./pretty-stdout");
const remap_1 = require("./remap");
const utils_1 = require("./utils");
let logContext = process.env.LOG_CONTEXT ?? (0, nanoid_1.nanoid)();
let curMeta = {};
const problems = new utils_1.ProblemStream();
// istanbul ignore if: not easily testable
if (is_1.default.string(process.env.LOG_LEVEL)) {
    process.env.LOG_LEVEL = process.env.LOG_LEVEL.toLowerCase().trim();
}
const stdout = {
    name: 'stdout',
    level: (0, utils_1.validateLogLevel)(process.env.LOG_LEVEL, 'info'),
    stream: process.stdout,
};
// istanbul ignore if: not testable
if (process.env.LOG_FORMAT !== 'json') {
    // TODO: typings (#9615)
    const prettyStdOut = new pretty_stdout_1.RenovateStream();
    prettyStdOut.pipe(process.stdout);
    stdout.stream = prettyStdOut;
    stdout.type = 'raw';
}
const bunyanLogger = bunyan.createLogger({
    name: 'renovate',
    serializers: {
        body: config_serializer_1.default,
        cmd: cmd_serializer_1.default,
        config: config_serializer_1.default,
        migratedConfig: config_serializer_1.default,
        originalConfig: config_serializer_1.default,
        presetConfig: config_serializer_1.default,
        oldConfig: config_serializer_1.default,
        newConfig: config_serializer_1.default,
        err: err_serializer_1.default,
    },
    streams: [
        stdout,
        {
            name: 'problems',
            level: 'warn',
            stream: problems,
            type: 'raw',
        },
    ].map(utils_1.withSanitizer),
});
const logFactory = (_level) => {
    return (p1, p2) => {
        let level = _level;
        if (p2) {
            // meta and msg provided
            const msg = p2;
            const meta = { logContext, ...curMeta, ...p1 };
            const remappedLevel = (0, remap_1.getRemappedLevel)(msg);
            // istanbul ignore if: not testable
            if (remappedLevel) {
                meta.oldLevel = level;
                level = remappedLevel;
            }
            bunyanLogger[level](meta, msg);
        }
        else if (is_1.default.string(p1)) {
            // only message provided
            const msg = p1;
            const meta = { logContext, ...curMeta };
            const remappedLevel = (0, remap_1.getRemappedLevel)(msg);
            // istanbul ignore if: not testable
            if (remappedLevel) {
                meta.oldLevel = level;
                level = remappedLevel;
            }
            bunyanLogger[level](meta, msg);
        }
        else {
            // only meta provided
            bunyanLogger[level]({ logContext, ...curMeta, ...p1 });
        }
    };
};
const loggerLevels = [
    'trace',
    'debug',
    'info',
    'warn',
    'error',
    'fatal',
];
exports.logger = { once: { reset: once_1.reset } };
loggerLevels.forEach((loggerLevel) => {
    exports.logger[loggerLevel] = logFactory(loggerLevel);
    const logOnceFn = (p1, p2) => {
        (0, once_1.once)(() => {
            const logFn = exports.logger[loggerLevel];
            if (is_1.default.undefined(p2)) {
                logFn(p1);
            }
            else {
                logFn(p1, p2);
            }
        }, logOnceFn);
    };
    exports.logger.once[loggerLevel] = logOnceFn;
});
// istanbul ignore if: not easily testable
if (is_1.default.string(process.env.LOG_FILE)) {
    // ensure log file directory exists
    const directoryName = upath_1.default.dirname(process.env.LOG_FILE);
    fs_extra_1.default.ensureDirSync(directoryName);
    addStream({
        name: 'logfile',
        path: process.env.LOG_FILE,
        level: (0, utils_1.validateLogLevel)(process.env.LOG_FILE_LEVEL, 'debug'),
    });
}
function setContext(value) {
    logContext = value;
}
function getContext() {
    return logContext;
}
// setMeta overrides existing meta, may remove fields if no longer existing
function setMeta(obj) {
    curMeta = { ...obj };
}
// addMeta overrides or adds fields but does not remove any
function addMeta(obj) {
    curMeta = { ...curMeta, ...obj };
}
// removeMeta removes the provided fields from meta
function removeMeta(fields) {
    Object.keys(curMeta).forEach((key) => {
        if (fields.includes(key)) {
            delete curMeta[key];
        }
    });
}
function addStream(stream) {
    bunyanLogger.addStream((0, utils_1.withSanitizer)(stream));
}
function levels(name, level) {
    bunyanLogger.levels(name, level);
}
function getProblems() {
    return problems.getProblems();
}
function clearProblems() {
    return problems.clearProblems();
}
//# sourceMappingURL=index.js.map