"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLogger = exports.prodLogger = exports.devLogger = void 0;
const sqlstring_1 = __importDefault(require("sqlstring"));
const ramda_1 = __importDefault(require("ramda"));
const colors = {
    red: '31',
    green: '32',
    yellow: '33', // WARNING
};
const withColor = (str, color = colors.green) => `\u001b[${color}m${str}\u001b[0m`;
const format = ({ requestId, duration, allSqlLines, query, values, showRestParams, ...json }) => {
    const restParams = JSON.stringify(json, null, 2);
    const durationStr = duration ? `(${duration}ms)` : '';
    const prefix = `${requestId || ''} ${durationStr}`.trim();
    if (query && values) {
        const queryMaxLines = 50;
        let queryStr = typeof query === 'string' ? query : JSON.stringify(query);
        queryStr = queryStr.replaceAll(/\$(\d+)/g, '?');
        let formatted = sqlstring_1.default.format(queryStr, values).split('\n');
        if (formatted.length > queryMaxLines && !allSqlLines) {
            formatted = ramda_1.default.take(queryMaxLines / 2, formatted)
                .concat(['.....', '.....', '.....'])
                .concat(ramda_1.default.takeLast(queryMaxLines / 2, formatted));
        }
        return `${prefix}\n--\n  ${formatted.join('\n')}\n--${showRestParams ? `\n${restParams}` : ''}`;
    }
    else if (query) {
        return `${prefix}\n--\n${JSON.stringify(query, null, 2)}\n--${showRestParams ? `\n${restParams}` : ''}`;
    }
    return `${prefix}${showRestParams ? `\n${restParams}` : ''}`;
};
const devLogger = (filterByLevel) => (type, { error, warning, ...restParams }) => {
    const logWarning = () => console.log(`${withColor(type, colors.yellow)}: ${format({ ...restParams, allSqlLines: true, showRestParams: true })} \n${withColor(warning || '', colors.yellow)}`);
    const logError = () => console.log(`${withColor(type, colors.red)}: ${format({ ...restParams, allSqlLines: true, showRestParams: true })} \n${error}`);
    const logDetails = (showRestParams) => console.log(`${withColor(type)}: ${format({ ...restParams, showRestParams })}`);
    if (error) {
        logError();
        return;
    }
    // eslint-disable-next-line default-case
    switch (filterByLevel.toLowerCase()) {
        case 'trace': {
            if (!error && !warning) {
                logDetails(true);
                break;
            }
        }
        // falls through, trick from 90x, levels inheritance, David Blaine: Street Magic
        case 'info': {
            if (!error && !warning && [
                'Executing SQL',
                'Streaming SQL',
                'Executing Load Pre Aggregation SQL',
                'Load Request Success',
                'Performing query',
                'Performing query completed',
                'Streaming successfully completed',
            ].includes(type)) {
                logDetails();
                break;
            }
        }
        // falls through, trick from 90x, levels inheritance, David Blaine: Street Magic
        case 'warn': {
            if (!error && warning) {
                logWarning();
                break;
            }
        }
        // falls through, trick from 90x, levels inheritance, David Blaine: Street Magic
        case 'error': {
            if (error) {
                logError();
                break;
            }
        }
    }
};
exports.devLogger = devLogger;
const prodLogger = (filterByLevel) => (message, params) => {
    const { error, warning } = params;
    if (!params.level) {
        if (error) {
            params.level = 'error';
        }
        else if (warning) {
            params.level = 'warn';
        }
        else {
            params.level = 'info';
        }
    }
    const logMessage = () => {
        const { level, timestamp, ...restParams } = params;
        console.log(JSON.stringify({
            timestamp,
            level,
            message,
            ...restParams,
        }));
    };
    // eslint-disable-next-line default-case
    switch (filterByLevel.toLowerCase()) {
        case 'trace': {
            if (!error && !warning) {
                logMessage();
                break;
            }
        }
        // falls through, trick from 90x, levels inheritance, David Blaine: Street Magic
        case 'info':
            if ([
                'REST API Request',
            ].includes(message)) {
                logMessage();
                break;
            }
        // falls through, trick from 90x, levels inheritance, David Blaine: Street Magic
        case 'warn': {
            if (!error && warning) {
                logMessage();
                break;
            }
        }
        // falls through, trick from 90x, levels inheritance, David Blaine: Street Magic
        case 'error': {
            if (error) {
                logMessage();
                break;
            }
        }
    }
};
exports.prodLogger = prodLogger;
const createLogger = (production, filterByLevel = 'info') => {
    switch (filterByLevel.toLowerCase()) {
        case 'trace':
        case 'info':
        case 'warn':
        case 'error':
            break;
        // not used, but let's allow
        case 'debug':
            break;
        default:
            throw new Error(`Invalid log level: ${filterByLevel}`);
    }
    if (production) {
        return (0, exports.prodLogger)(filterByLevel);
    }
    else {
        return (0, exports.devLogger)(filterByLevel);
    }
};
exports.createLogger = createLogger;
//# sourceMappingURL=logger.js.map