import { Algo } from '@alessiofrittoli/crypto-algorithm/types';
import { Variant } from '@alessiofrittoli/crypto-encoder/Base32';
import { OTP } from './types.js';

declare class Otp {
    /**
     * Defines the default used digits.
     *
     */
    static Digits: OTP.Digits;
    /**
     * Defines the default secret key encoding.
     *
     */
    static Encoding: OTP.Encoding;
    /**
     * Defines the default secret key hash algorithm.
     *
     */
    static Algorithm: Algo.Hash;
    /**
     * Defines the default Base32 encoding variant.
     *
     */
    static Base32Variant: Variant;
    /**
     * Converts a digest to a token of a specified length.
     *
     * @param	digest	The digest Buffer.
     * @param	digits	( Optional ) The OTP token digits count ( usually 6 | 8 ). Default: `6`.
     *
     * [RFC 4226 - IETF](https://datatracker.ietf.org/doc/html/rfc4226#section-5.3)
     *
     * @returns	The OTP token.
     */
    static DigestToToken(digest: Buffer, digits?: OTP.Digits): string;
    /**
     * Takes a OTP secret and derives the HMAC key for use in token generation.
     *
     * @param secret	The OTP secret.
     * @param encoding	The OTP secret encoding.
     *
     * @returns The HMAC HEX Key.
     */
    static HmacKey(secret: string, encoding: OTP.Encoding): string;
    /**
     * Create HMAC digest.
     *
     * @param	algorithm	The HMAC algorithm. Usually `SHA-1` is used for the 20 bytes HEX secret key.
     * @param	hmacKey		The HMAC key derived from OTP secret. @see {@link OTP.HmacKey}.
     * @param	counter		The OTP formatted counter string.
     *
     * @returns	The HMAC digest.
     */
    static createDigest(algorithm: Algo.Hash, hmacKey: string, counter: string): Buffer;
    protected static padStart: (value: string | number, maxLength: number, character?: string) => string;
    /**
     * Generate 20 bytes HMAC-SHA-1 HEX secret associated with the given string.
     *
     * @param string ( Optional ) The string to encrypt into the HMAC secret key.
     *
     * @returns The 20 bytes SHA-1 HEX secret key.
     */
    static Seed(string?: string): string;
    /**
     * Generates a key of a certain length (default 32) from A-Z, a-z, 0-9, and symbols (if requested).
     *
     * @param	length	( Optional ) The lenght of the key. Default: `40`.
     * @param	symbols	( Optional ) Whether to use symbols or not. Default: `false`.
     *
     * @returns	The generated key.
     */
    static GenerateSecretASCII(length?: number, symbols?: boolean): string;
    /**
     * Get the otpauth URL string.
     *
     * https://docs.yubico.com/yesdk/users-manual/application-oath/uri-string-format.html
     *
     * @param	options The AuthURLOptions object.
     * @returns	The otpauth URL string.
     */
    protected static GetAuthURL<T extends OTP.Type>(options: OTP.AuthURLOptions<T>): string;
    /**
     * Retrieve the Secret Key in different encodings.
     *
     * @param	options The GetSecretsOptions object.
     * @returns	An object with Secret Key in different encodings, indexed by encoding name.
     */
    static GetSecrets(options: OTP.GetSecretsOptions): OTP.Secrets;
}

/**
 * HMAC-Based One-Time Password.
 *
 * [RFC 4226 - IETF](https://datatracker.ietf.org/doc/html/rfc4226)
 */
declare class Hotp extends Otp {
    /**
     * Verify a HOTP token.
     *
     * @param	options The HOTP options. @see {@link OTP.HOTP.GetDeltaOptions}
     * @returns	True if the given HOTP token is valid, false otherwise.
     */
    static Verify(options: OTP.HOTP.GetDeltaOptions): boolean;
    /**
     * Get HOTP token delta.
     *
     * If the token is valid, the delta will match the step on which the given token has been validated with the given counter.
     *
     * @param	options The HOTP options. @see {@link OTP.HOTP.GetDeltaOptions}
     * @returns	The delta number, null otherwise.
     */
    static GetDelta(options: OTP.HOTP.GetDeltaOptions): number | null;
    /**
     * Get TOTP token delta.
     *
     * If the token is valid, the delta will match the step on which the given token has been validated with the given counter.
     *
     * @param	options The TOTP options. @see {@link OTP.TOTP.GetDeltaOptions}
     * @returns	The delta number, null otherwise.
     */
    static GetDelta(options: OTP.HOTP.GetDeltaOptions, twoSidedWindow?: boolean): number | null;
    /**
     * Generates a HMAC-Based One-Time Password (HOTP)
     *
     * @param	options The HOTP options. @see {@link OTP.HOTP.GetTokenOptions}
     * @returns	The HOTP token.
     */
    static GetToken(options: OTP.HOTP.GetTokenOptions): string;
    /**
     * Generates a HMAC digest.
     *
     * @param	options The HOTP options. @see {@link OTP.HOTP.GetTokenOptions}
     * @returns The HMAC digest Buffer.
     */
    static Digest(options: Omit<OTP.HOTP.GetTokenOptions, 'digits'>): Buffer;
    /**
     * Formats a given counter into a string counter.
     *
     * @param counter The HOTP counter.
     */
    static Counter(counter: number): string;
    /**
     * Get the otpauth URL string.
     *
     * https://docs.yubico.com/yesdk/users-manual/application-oath/uri-string-format.html
     *
     * @param	options The AuthURLOptions object.
     * @returns	The otpauth URL string.
     */
    static AuthURL(options: Omit<OTP.AuthURLOptions<'hotp'>, 'type'>): string;
}

/**
 * Time-Based One-Time Password.
 *
 * [RFC 6238 - IETF](https://datatracker.ietf.org/doc/html/rfc6238)
 */
declare class Totp extends Otp {
    /**
     * The TOTP default period.
     *
     */
    static Period: OTP.TOTP.Period;
    /**
     * Verify a TOTP token.
     *
     * @param	options The TOTP options. @see {@link OTP.TOTP.GetDeltaOptions}
     * @returns	True if the given TOTP token is valid, false otherwise.
     */
    static Verify(options: OTP.TOTP.GetDeltaOptions): boolean;
    /**
     * Get OTP token delta.
     * If the token is valid, the delta will match the step on which the given token has been validated with the given counter.
     *
     * @param	options The TOTP options. @see {@link OTP.TOTP.GetDeltaOptions}
     * @returns	The delta number, null otherwise.
     */
    static GetDelta(options: OTP.TOTP.GetDeltaOptions): number | null;
    /**
     * Generates a Time-Based One-Time Password (TOTP).
     *
     * @param	options The TOTP options. @see {@link Otp.TOTP.GetTokenOptions}
     * @returns The TOTP token.
     */
    static GetToken(options: OTP.TOTP.GetTokenOptions): string;
    /**
     * Calculate counter value based on given options.
     * A counter value converts a TOTP time into a counter value by finding the number of time steps
     * that have passed since the epoch to the current time.
     *
     * @param	options The TOTP counter options. @see {@link OTP.TOTP.CounterOptions}
     * @returns	The calculated counter value.
     */
    static Counter(options?: OTP.TOTP.CounterOptions): number;
    /**
     * Calculates the Date object representing the next time tick for a TOTP counter.
     *
     * @param	options The TOTP counter options. @see {@link OTP.TOTP.CounterOptions}
     * @returns A `Date` object representing the start of the next TOTP time step.
     */
    static NextTick(options?: OTP.TOTP.CounterOptions): Date;
    /**
     * Get the otpauth URL string.
     *
     * https://docs.yubico.com/yesdk/users-manual/application-oath/uri-string-format.html
     *
     * @param	options The AuthURLOptions object.
     * @returns	The otpauth URL string.
     */
    static AuthURL(options: Omit<OTP.AuthURLOptions<'totp'>, 'type'>): string;
}

export { Hotp, OTP, Otp, Totp };
