"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resetTimingData = exports.getTimingData = exports.markTime = void 0;
exports.summariseTimingData = summariseTimingData;
const types_1 = require("@mongosh/types");
const v8_1 = __importDefault(require("v8"));
let jsTimingEntries = [];
function linkTimingInterface() {
    const boxedNode = process.boxednode;
    if (boxedNode) {
        return {
            markTime: boxedNode.markTime,
            getTimingData: boxedNode.getTimingData,
            resetTimingData: () => undefined,
        };
    }
    return {
        markTime: (category, label) => jsTimingEntries.push([category, label, process.hrtime.bigint()]),
        getTimingData: () => {
            const data = jsTimingEntries.sort((a, b) => Number(a[2] - b[2]));
            return data.map(([category, label, time]) => [
                category,
                label,
                Number(time - data[0][2]),
            ]);
        },
        resetTimingData: () => {
            jsTimingEntries = [];
        },
    };
}
function summariseTimingData(timingData) {
    const durationByCategory = new Map();
    let lastTimestamp = 0;
    for (const [category, _, time] of timingData) {
        const durationInNs = time - lastTimestamp;
        const durationInMs = durationInNs / 1_000_000;
        const durationSum = (durationByCategory.get(category) || 0) + durationInMs;
        durationByCategory.set(category, durationSum);
        lastTimestamp = time;
    }
    return Object.fromEntries(durationByCategory.entries());
}
const timing = linkTimingInterface();
exports.markTime = timing.markTime;
exports.getTimingData = timing.getTimingData;
exports.resetTimingData = timing.resetTimingData;
function installExitHandler() {
    if (process.env.MONGOSH_SHOW_TIMING_DATA) {
        process.on('exit', function () {
            const rawTimingData = (0, exports.getTimingData)();
            if (process.env.MONGOSH_SHOW_TIMING_DATA === 'json') {
                console.log(JSON.stringify(rawTimingData));
            }
            else {
                console.table(rawTimingData.map(([category, label, time], i) => [
                    category,
                    label,
                    `${(time / 1_000_000).toFixed(2)}ms`,
                    i > 0
                        ? `+${((time - rawTimingData[i - 1][2]) / 1_000_000).toFixed(2)}ms`
                        : '',
                ]));
            }
        });
    }
}
if (v8_1.default?.startupSnapshot?.isBuildingSnapshot?.()) {
    v8_1.default.startupSnapshot.addDeserializeCallback(() => {
        installExitHandler();
    });
}
else {
    installExitHandler();
}
(0, exports.markTime)(types_1.TimingCategories.REPLInstantiation, 'cli-repl timing initialized');
//# sourceMappingURL=startup-timing.js.map