"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * Random number generator that works across modern JavaScript environments.
 *
 * This implementation uses the Web Crypto API which is available in:
 * - Node.js 6+ via require('crypto').randomBytes()
 * - Node.js 18+ via globalThis.crypto
 * - Modern browsers via globalThis.crypto, self.crypto, or window.crypto
 * - Web Workers and Service Workers via self.crypto
 * - Deno and Bun via globalThis.crypto
 *
 * @throws {Error} If no secure random number generator is available
 */
class Rand {
    getRandomValues(obj, n) {
        const arr = new Uint8Array(n);
        obj.crypto.getRandomValues(arr);
        return Array.from(arr);
    }
    constructor() {
        const noRand = () => {
            throw new Error('No secure random number generator is available in this environment.');
        };
        this._rand = noRand; // Assign the function
        // Try globalThis.crypto (works in Node.js 18+, modern browsers, and Deno)
        if (typeof globalThis !== 'undefined' && typeof globalThis.crypto?.getRandomValues === 'function') {
            this._rand = (n) => {
                return this.getRandomValues(globalThis, n);
            };
            return;
        }
        // Node.js fallback for versions < 18
        if (typeof process !== 'undefined' && process.release?.name === 'node') {
            try {
                // eslint-disable-next-line @typescript-eslint/no-var-requires
                const crypto = require('node:crypto');
                if (typeof crypto.randomBytes === 'function') {
                    this._rand = (n) => {
                        return Array.from(crypto.randomBytes(n));
                    };
                    return;
                }
            }
            catch (_cryptoModuleUnavailable) {
                // node:crypto not available in this runtime; continue to other crypto API checks
            }
        }
        // Try self.crypto (Web Workers and Service Workers)
        if (typeof globalThis.self !== 'undefined' && typeof globalThis.self.crypto?.getRandomValues === 'function') {
            this._rand = (n) => {
                return this.getRandomValues(globalThis.self, n);
            };
            return;
        }
        // Try window.crypto (browsers)
        if (typeof globalThis.window !== 'undefined' && typeof globalThis.window.crypto?.getRandomValues === 'function') {
            this._rand = (n) => {
                return this.getRandomValues(globalThis.window, n);
            };
            return;
        }
        // No crypto available
        this._rand = noRand;
    }
    generate(len) {
        return this._rand(len);
    }
}
let ayn = null;
/**
 * Generates a sequence of pseudo-random bytes with the given length.
 *
 * @param len - The number of bytes to generate
 *
 * @returns The generated bytes
 *
 * @example
 * import Random from '@bsv/sdk/primitives/Random'
 * const bytes = Random(32) // Produces 32 random bytes
 */
const Random = (len) => {
    ayn ?? (ayn = new Rand());
    return ayn.generate(len);
};
exports.default = Random;
//# sourceMappingURL=Random.js.map