"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
const node_assert_1 = require("node:assert");
const internal_1 = require("@fluidframework/telemetry-utils/internal");
const internal_2 = require("@fluidframework/test-runtime-utils/internal");
const containerRuntime_js_1 = require("../containerRuntime.js");
const dataStoreRegistry_js_1 = require("../dataStoreRegistry.js");
// Capture the full property descriptor (not just the value) so we can restore the original getter-backed property after tests override it.
// Uses an IIFE so the assert narrows the type to a definite PropertyDescriptor, avoiding
// non-null assertions in restoreNavigator (TypeScript can't track narrowing across function boundaries).
const originalNavigatorDescriptor = (() => {
    const desc = Object.getOwnPropertyDescriptor(globalThis, "navigator");
    (0, node_assert_1.strict)(desc !== undefined, "navigator must be defined in the test environment (requires Node 22)");
    return desc;
})();
function setNavigator(navigator) {
    // In Node 22+, globalThis.navigator is a read-only getter, so direct
    // assignment throws. Use Object.defineProperty to override it.
    Object.defineProperty(globalThis, "navigator", {
        value: navigator,
        writable: true,
        configurable: true,
    });
}
function restoreNavigator() {
    Object.defineProperty(globalThis, "navigator", originalNavigatorDescriptor);
}
describe("Hardware Stats", () => {
    let mockLogger = new internal_1.MockLogger();
    let mockContext = {
        deltaManager: new internal_2.MockDeltaManager(),
        audience: new internal_2.MockAudience(),
        quorum: new internal_2.MockQuorumClients(),
        taggedLogger: mockLogger,
        clientDetails: { capabilities: { interactive: true } },
        updateDirtyContainerState: (dirty) => { },
        getLoadedFromVersion: () => undefined,
    };
    const getDeviceSpecEvents = () => mockLogger.events.filter((event) => event.eventName === "DeviceSpec");
    const loadContainer = async () => containerRuntime_js_1.ContainerRuntime.loadRuntime2({
        context: mockContext,
        registry: new dataStoreRegistry_js_1.FluidDataStoreRegistry([]),
        runtimeOptions: {
            summaryOptions: {
                summaryConfigOverrides: { state: "disabled" },
            },
        },
        provideEntryPoint: async () => ({
            myProp: "myValue",
        }),
        existing: false,
    });
    afterEach(() => {
        restoreNavigator();
    });
    beforeEach(async () => {
        mockLogger = new internal_1.MockLogger();
        mockContext = {
            deltaManager: new internal_2.MockDeltaManager(),
            audience: new internal_2.MockAudience(),
            quorum: new internal_2.MockQuorumClients(),
            taggedLogger: mockLogger,
            clientDetails: { capabilities: { interactive: true } },
            updateDirtyContainerState: (dirty) => { },
            getLoadedFromVersion: () => undefined,
        };
    });
    it("should generate correct hardware stats with browser-like navigator", async () => {
        const navigator = {
            deviceMemory: 10,
            hardwareConcurrency: 8,
        };
        setNavigator(navigator);
        // testing function
        const { deviceMemory, hardwareConcurrency } = (0, containerRuntime_js_1.getDeviceSpec)();
        node_assert_1.strict.strictEqual(deviceMemory, 10, "incorrect deviceMemory value");
        node_assert_1.strict.strictEqual(hardwareConcurrency, 8, "incorrect hardwareConcurrency value");
        await loadContainer();
        // checking telemetry
        const events = getDeviceSpecEvents();
        (0, node_assert_1.strict)(events !== undefined, "No deviceSpec event found");
        node_assert_1.strict.strictEqual(events[0].deviceMemory, 10, "incorrect deviceMemory logged");
        node_assert_1.strict.strictEqual(events[0].hardwareConcurrency, 8, "incorrect hardwareConcurrency logged");
    });
    // If Node ever adds support for deviceMemory, we can collapse both tests into one
    // and stop mocking navigator entirely.
    it("should generate correct hardware stats with Node-native navigator", async () => {
        // Node 22+ provides a built-in navigator with hardwareConcurrency but not deviceMemory.
        restoreNavigator();
        // testing function
        const { deviceMemory, hardwareConcurrency } = (0, containerRuntime_js_1.getDeviceSpec)();
        node_assert_1.strict.strictEqual(deviceMemory, undefined, "deviceMemory should be undefined on Node");
        node_assert_1.strict.strictEqual(typeof hardwareConcurrency, "number", "hardwareConcurrency should be a number on Node");
        await loadContainer();
        // checking telemetry
        const events = getDeviceSpecEvents();
        (0, node_assert_1.strict)(events !== undefined, "No deviceSpec event found");
        node_assert_1.strict.strictEqual(events[0].deviceMemory, undefined, "deviceMemory should be undefined on Node");
        node_assert_1.strict.strictEqual(typeof events[0].hardwareConcurrency, "number", "hardwareConcurrency should be a number on Node");
    });
});
//# sourceMappingURL=hardwareStats.spec.js.map