// This Source Code Form is subject to the terms of the Mozilla Public
// License, v2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/
const MAX_SAMPLE_SIZE = 100;
export function constructKeyForTopicRenderMetrics(key, topic) {
    return `${key}:${topic}`;
}
function bytesToMegabits(bytes) {
    return (bytes / (1024 * 1024)) * 8;
}
class MetricsManager {
    metrics = {};
    getMetrics() {
        return this.metrics;
    }
}
export class EventMetricsManager extends MetricsManager {
    calculate(topic) {
        const topicMetrics = this.metrics[topic];
        if (!topicMetrics) {
            return undefined;
        }
        let totalInterval = 0;
        for (let i = 1; i < topicMetrics.length; ++i) {
            totalInterval += topicMetrics[i - 1] - topicMetrics[i];
        }
        if (isNaN(totalInterval)) {
            return undefined;
        }
        const fps = 1_000 / (totalInterval / (topicMetrics.length - 1));
        return Math.round(fps);
    }
    registerEvent(topic) {
        const currentTime = performance.now();
        // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
        this.metrics[topic] ??= [];
        this.metrics[topic].unshift(currentTime);
        if (this.metrics[topic].length > MAX_SAMPLE_SIZE) {
            this.metrics[topic].length = MAX_SAMPLE_SIZE;
        }
    }
}
export class ThroughputMetricsManager extends MetricsManager {
    calculate(topic) {
        const topicMetrics = this.metrics[topic];
        if (!topicMetrics || topicMetrics.length < 2 || !topicMetrics.at(0) || !topicMetrics.at(-1)) {
            return undefined;
        }
        // Get time span in seconds
        // biome-ignore lint/style/noNonNullAssertion: <explanation>
        const timeSpanMs = topicMetrics.at(0).timestamp - topicMetrics.at(-1).timestamp;
        const timeSpanSec = timeSpanMs / 1000;
        if (timeSpanSec === 0) {
            return undefined;
        }
        // Sum up all values (bytes)
        const totalBytes = topicMetrics.reduce((sum, metric) => sum + metric.value, 0);
        // Calculate bytes per second
        const bytesPerSecond = totalBytes / timeSpanSec;
        // Return rounded value
        return Number(bytesToMegabits(bytesPerSecond).toFixed(2));
    }
    registerEvent(topic, value) {
        const timestamp = performance.now();
        this.metrics[topic] ??= [];
        this.metrics[topic].unshift({ timestamp, value });
        if (this.metrics[topic].length > MAX_SAMPLE_SIZE) {
            this.metrics[topic].length = MAX_SAMPLE_SIZE;
        }
    }
}
const [globalInputEventMetricsManager, globalDecodeMetricsManager, globalRenderMetricsManager, globalThroughputMetricsManager,] = [
    new EventMetricsManager(),
    new EventMetricsManager(),
    new EventMetricsManager(),
    new ThroughputMetricsManager(),
];
export { 
// Event Metrics Manager which tracks the FPS of incoming messages like annotations or image frames
globalInputEventMetricsManager, 
// Event Metrics Manager which tracks the FPS of message decoding
globalDecodeMetricsManager, 
// Event Metrics Manager which tracks the FPS of rendering in Panels
globalRenderMetricsManager, 
// Throughput Metrics Manager which tracks the throughput of incoming data
globalThroughputMetricsManager, };
//# sourceMappingURL=metrics-manager.js.map