"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Profiler = void 0;
var tslib_1 = require("tslib");
var node_perf_hooks_1 = require("node:perf_hooks");
var crypto_1 = tslib_1.__importDefault(require("crypto"));
var defaultMeta = { datadog: true };
var Profiler = (function () {
    function Profiler(_a) {
        var logger = _a.logger, at = _a.at, logLevel = _a.logLevel, detail = tslib_1.__rest(_a, ["logger", "at", "logLevel"]);
        this.marks = new Map();
        this.logger = logger;
        this.at = at;
        this.detail = detail;
    }
    Profiler.prototype.warn = function (data) {
        this.logger.warn(tslib_1.__assign({ at: this.at }, data));
    };
    Profiler.prototype.logMeasure = function (data) {
        this.logger.debug(tslib_1.__assign(tslib_1.__assign({ at: this.at }, defaultMeta), data));
    };
    Profiler.prototype.start = function (task, detail) {
        var _this = this;
        var start = crypto_1.default.randomUUID();
        var startTime = this.mark(start, detail);
        return {
            startTime: startTime,
            stop: function (_detail) { return _this.measure(task, tslib_1.__assign(tslib_1.__assign({ from: start }, (detail !== null && detail !== void 0 ? detail : {})), (_detail !== null && _detail !== void 0 ? _detail : {}))); },
        };
    };
    Profiler.prototype.mark = function (label, detail) {
        var _a;
        var currentTime = node_perf_hooks_1.performance.now();
        this.detail = tslib_1.__assign(tslib_1.__assign({}, ((_a = this.detail) !== null && _a !== void 0 ? _a : {})), (detail !== null && detail !== void 0 ? detail : {}));
        this.marks.set(label, { time: currentTime, detail: detail });
        return currentTime;
    };
    Profiler.prototype.measure = function (task, params) {
        var _a, _b;
        var from = params.from, to = params.to, detail = tslib_1.__rest(params, ["from", "to"]);
        var startMark = this.marks.get(from);
        var endMark = to ? this.marks.get(to) : undefined;
        if (!startMark) {
            this.warn(tslib_1.__assign({ message: "Cannot find start mark for label \"".concat(from, "\".") }, this.detail));
            return;
        }
        var endTime = (_a = endMark === null || endMark === void 0 ? void 0 : endMark.time) !== null && _a !== void 0 ? _a : node_perf_hooks_1.performance.now();
        var duration = endTime - startMark.time;
        var _c = tslib_1.__assign(tslib_1.__assign({}, ((_b = this.detail) !== null && _b !== void 0 ? _b : {})), (detail !== null && detail !== void 0 ? detail : {})), message = _c.message, combinedDetail = tslib_1.__rest(_c, ["message"]);
        var defaultMessage = "Profiler Log: ".concat(task);
        this.logMeasure({
            task: task,
            duration: duration,
            message: message !== null && message !== void 0 ? message : defaultMessage,
            data: combinedDetail,
        });
        return duration;
    };
    Profiler.prototype.measureAsync = function (pr, task, detail) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var startTime, result, endTime, duration, _a, message, combinedDetail, defaultMessage;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        startTime = node_perf_hooks_1.performance.now();
                        _b.label = 1;
                    case 1:
                        _b.trys.push([1, , 3, 4]);
                        return [4, pr];
                    case 2:
                        result = _b.sent();
                        return [2, result];
                    case 3:
                        endTime = node_perf_hooks_1.performance.now();
                        duration = endTime - startTime;
                        _a = tslib_1.__assign({}, detail), message = _a.message, combinedDetail = tslib_1.__rest(_a, ["message"]);
                        defaultMessage = "Profiler Log: ".concat(task);
                        this.logMeasure({
                            task: task,
                            duration: duration,
                            message: message !== null && message !== void 0 ? message : defaultMessage,
                            data: combinedDetail,
                        });
                        return [7];
                    case 4: return [2];
                }
            });
        });
    };
    Profiler.prototype.measureSync = function (fn, task, detail) {
        var startTime = node_perf_hooks_1.performance.now();
        try {
            var result = fn();
            return result;
        }
        finally {
            var endTime = node_perf_hooks_1.performance.now();
            var duration = endTime - startTime;
            var _a = tslib_1.__assign({}, detail), message = _a.message, combinedDetail = tslib_1.__rest(_a, ["message"]);
            var defaultMessage = "Profiler Log: ".concat(task);
            this.logMeasure({
                task: task,
                duration: duration,
                message: message !== null && message !== void 0 ? message : defaultMessage,
                data: combinedDetail,
            });
        }
    };
    return Profiler;
}());
exports.Profiler = Profiler;
//# sourceMappingURL=Profiler.js.map