"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TRUNCATED_MESSAGE_SUFFIX = exports.VALUE_TO_STRING_DEFAULT_LIMIT = void 0;
exports.logInternal = logInternal;
exports.logCliOutput = logCliOutput;
exports.findResultSeverityToLogLevel = findResultSeverityToLogLevel;
exports.logWebUI = logWebUI;
exports.logWebUIAndCliOutput = logWebUIAndCliOutput;
exports.valueToString = valueToString;
exports.maybeTruncateLongMessage = maybeTruncateLongMessage;
exports.formatTimestamp = formatTimestamp;
exports.logErrorVerbose = logErrorVerbose;
exports.logPromiseSettledRejections = logPromiseSettledRejections;
exports.getPromiseSettledValues = getPromiseSettledValues;
exports.promiseRejectionMiddlewareMetric = promiseRejectionMiddlewareMetric;
const mablscriptFind_1 = require("@mablhq/test-model/mablscriptFind");
const loggingProvider_1 = require("../providers/logging/loggingProvider");
const moment_1 = __importDefault(require("moment"));
const constants_1 = require("../core/constants");
const pureUtil_1 = require("./pureUtil");
const InternalMetricsTrackingSingleton_1 = require("./InternalMetricsTrackingSingleton");
exports.VALUE_TO_STRING_DEFAULT_LIMIT = 2048;
exports.TRUNCATED_MESSAGE_SUFFIX = '…[truncated]';
function logInternal(logLine, ...meta) {
    loggingProvider_1.logger.debug(logLine, meta);
}
function logCliOutput(logLevel, logLine) {
    switch (logLevel) {
        case loggingProvider_1.LogLevel.Error:
            loggingProvider_1.logger.error(logLine);
            break;
        case loggingProvider_1.LogLevel.Warn:
            loggingProvider_1.logger.warn(logLine);
            break;
        case loggingProvider_1.LogLevel.Info:
            loggingProvider_1.logger.info(logLine);
            break;
        case loggingProvider_1.LogLevel.Debug:
        default:
            loggingProvider_1.logger.debug(logLine);
    }
}
function findResultSeverityToLogLevel(severity) {
    switch (severity) {
        case mablscriptFind_1.FindResultLogSeverity.Error:
            return loggingProvider_1.LogLevel.Error;
        case mablscriptFind_1.FindResultLogSeverity.Warn:
            return loggingProvider_1.LogLevel.Warn;
        case mablscriptFind_1.FindResultLogSeverity.Info:
            return loggingProvider_1.LogLevel.Info;
        case mablscriptFind_1.FindResultLogSeverity.Debug:
        default:
            return loggingProvider_1.LogLevel.Debug;
    }
}
function logWebUI(logLine, logLevel, executionContext, metadata) {
    metadata = metadata ? JSON.parse(JSON.stringify(metadata)) : {};
    metadata.shouldOutputInConsole = false;
    logWebUIAndCliOutput(logLine, logLevel, executionContext, metadata);
}
function logWebUIAndCliOutput(logLine, logLevel, executionContext, metadata) {
    switch (logLevel) {
        case loggingProvider_1.LogLevel.Error:
            executionContext.log.error(logLine, metadata);
            break;
        case loggingProvider_1.LogLevel.Warn:
            executionContext.log.warning(logLine, metadata);
            break;
        case loggingProvider_1.LogLevel.Info:
            executionContext.log.info(logLine, metadata);
            break;
        case loggingProvider_1.LogLevel.Debug:
        default:
            executionContext.log.debug(logLine, metadata);
    }
}
function valueToString(value, maxLength = exports.VALUE_TO_STRING_DEFAULT_LIMIT) {
    let stringValue;
    if (typeof value === 'object') {
        stringValue = JSON.stringify(value);
    }
    else {
        stringValue = '' + value;
    }
    return maybeTruncateLongMessage(stringValue, maxLength);
}
function maybeTruncateLongMessage(message, maxLength) {
    return message.length <= maxLength
        ? message
        : message.slice(0, maxLength - exports.TRUNCATED_MESSAGE_SUFFIX.length) +
            exports.TRUNCATED_MESSAGE_SUFFIX;
}
function formatTimestamp(timeAsNumber) {
    if (!timeAsNumber) {
        return '';
    }
    return moment_1.default.utc(timeAsNumber).format(constants_1.ListTimeFormat);
}
function logErrorVerbose(error, context) {
    loggingProvider_1.logger.verbose(`Error Message: ${error.message}`);
    loggingProvider_1.logger.verbose(`Error Type: ${error.name}`);
    loggingProvider_1.logger.verbose(`Stack Trace:\n${error.stack}`);
    if (context) {
        loggingProvider_1.logger.verbose(`(error)(context) => ${JSON.stringify(context)}`);
    }
}
function logPromiseSettledRejections(promises, reThrow = false) {
    promises
        .filter(pureUtil_1.isRejectedPromise)
        .forEach((promise) => logErrorVerbose(promise.reason));
    const findRejectedPromise = promises.find(pureUtil_1.isRejectedPromise);
    if (findRejectedPromise && reThrow) {
        throw findRejectedPromise.reason;
    }
}
function getPromiseSettledValues(promises, reThrow = false) {
    logPromiseSettledRejections(promises, reThrow);
    return promises.filter(pureUtil_1.isFulfilledPromise).map((promise) => promise.value);
}
async function promiseRejectionMiddlewareMetric(promise, metricName, metricValue) {
    try {
        return await promise;
    }
    catch (error) {
        InternalMetricsTrackingSingleton_1.InternalMetricsTrackingSingleton.getInstance().addMetric(metricName, metricValue);
        throw error;
    }
}
