import { type ScryptOptions } from 'node:crypto';
// export declare const MAX_UINT32: number;
// export declare const MAX_UINT24: number;

import { promisify } from 'node:util';
import { randomBytes, scrypt } from 'node:crypto';
import phc from '@phc/format';

/**
 * Validates a number to be within a given range.
 */
export class RangeValidator {
    // static validate(label: string, value: unknown, range: [number, number]): void;
    static validate(label: string, value: unknown, range: [number, number]): void {
        if (typeof value !== 'number' || !Number.isInteger(value)) {
            throw new TypeError(`The "${label}" option must be an integer`);
        }
        const [min, max] = range;
        if (value < min || value > max) {
            throw new TypeError(`The "${label}" option must be in the range (${min} <= ${label} <= ${max})`);
        }
    }
}
/**
 * Validates a value to be one of the allowed values
 */
export class EnumValidator {
    // static validate(label: string, value: unknown, allowedValues: any[]): void;
    static validate(label: string, value: unknown, allowedValues: any[]): void {
        if (!allowedValues.includes(value)) {
            throw new TypeError(`The "${label}" option must be one of: ${allowedValues}`);
        }
    }
}
/**
 * Async function to generate random bytes
 */
// export declare const randomBytesAsync: (arg1: number) => Promise<Buffer>;
export const randomBytesAsync: (arg1: number) => Promise<Buffer> = promisify(randomBytes);
/**
 * Async version of scrypt.
 */
// export declare const scryptAsync: (arg1: string, arg2: Buffer, arg3: number, arg4: ScryptOptions) => Promise<Buffer>;
export const scryptAsync: (arg1: string, arg2: Buffer, arg3: number, arg4: ScryptOptions) => Promise<Buffer> = promisify(scrypt);

export class PhcFormatter {
    /**
     * Serialize salt and hash with predefined options.
     */
    serialize(salt: Buffer, hash: Buffer, options: any): string {
        return phc.serialize({
            id: options.id,
            version: options.version,
            params: options.params,
            salt,
            hash,
        });
    }
    /**
     * Deserialize a PHC string to an object
     */
    deserialize(phcString: string): DeserializeResult {
        return phc.deserialize(phcString);
    }
}
