/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as path from "path";
import { NativeLoggerCategory } from "@bentley/imodeljs-native";
import { BentleyLoggerCategory, Logger, LogLevel, ProcessDetector } from "@itwin/core-bentley";
import { BackendLoggerCategory } from "../BackendLoggerCategory";
import { IModelHost } from "../IModelHost";
import { IModelNative } from "../internal/NativePlatform";
/** Class for simple test timing */
export class Timer {
    _label;
    _start;
    constructor(label) {
        this._label = `\t${label}`;
        this._start = new Date();
    }
    end() {
        const stop = new Date();
        const elapsed = stop.getTime() - this._start.getTime();
        // eslint-disable-next-line no-console
        console.log(`${this._label}: ${elapsed}ms`);
    }
}
/**
 * Disables native code assertions from firing. This can be used by tests that intentionally
 * test failing operations. If those failing operations raise assertions in native code, the test
 * would fail unexpectedly in a debug build. In that case the native code assertions can be disabled with
 * this class.
 */
export class DisableNativeAssertions {
    _native;
    constructor() {
        this._native = new IModelNative.platform.DisableNativeAssertions();
    }
    [Symbol.dispose]() {
        if (!this._native)
            return;
        this._native.dispose();
        this._native = undefined;
    }
    /** @deprecated in 5.0 - will not be removed until after 2026-06-13. Use [Symbol.dispose] instead. */
    dispose() {
        this[Symbol.dispose]();
    }
}
export class TestUtils {
    static shouldLogToConsole() {
        return process.env.ITWINJS_CORE_BACKEND_TEST_LOG_TO_CONSOLE === "1";
    }
    static getCacheDir(fallback = undefined) {
        if (ProcessDetector.isMobileAppBackend) {
            return undefined; // Let the native side handle the cache.
        }
        return fallback ?? path.join(__dirname, ".cache"); // Set the cache dir to be under the lib directory.
    }
    /** Handles the startup of IModelHost.
     * The provided config is used and will override any of the default values used in this method.
     *
     * The default includes:
     * - cacheDir = path.join(__dirname, ".cache")
     * - allowSharedChannel = false;
     */
    static async startBackend(config) {
        const cfg = config ?? {};
        cfg.cacheDir = TestUtils.getCacheDir(cfg.cacheDir);
        cfg.allowSharedChannel ??= false; // Override default to test shared channel enforcement. Remove in version 5.0.
        cfg.implicitWriteEnforcement ??= "throw";
        await IModelHost.startup(cfg);
    }
    static async shutdownBackend() {
        return IModelHost.shutdown();
    }
    static setupLogging() {
        if (TestUtils.shouldLogToConsole())
            Logger.initializeToConsole();
        else
            Logger.initialize();
        Logger.setLevelDefault(LogLevel.Error);
    }
    static initDebugLogLevels(reset) {
        Logger.setLevelDefault(reset ? LogLevel.Error : LogLevel.Warning);
        Logger.setLevel(BentleyLoggerCategory.Performance, reset ? LogLevel.Error : LogLevel.Info);
        Logger.setLevel(BackendLoggerCategory.IModelDb, reset ? LogLevel.Error : LogLevel.Trace);
        Logger.setLevel(NativeLoggerCategory.DgnCore, reset ? LogLevel.Error : LogLevel.Trace);
        Logger.setLevel(NativeLoggerCategory.BeSQLite, reset ? LogLevel.Error : LogLevel.Trace);
    }
    // Setup typical programmatic log level overrides here
    // Convenience method used to debug specific tests/fixtures
    static setupDebugLogLevels() {
        TestUtils.initDebugLogLevels(false);
    }
    static resetDebugLogLevels() {
        TestUtils.initDebugLogLevels(true);
    }
}
// The very first "before" run to initially setup the logging and initial backend.
before(async () => {
    TestUtils.setupLogging();
    await TestUtils.startBackend();
});
after(async () => {
    await TestUtils.shutdownBackend();
});
//# sourceMappingURL=TestUtils.js.map