import { Redis } from '@upstash/redis';

type RetryConfig = {
    /**
     * The number of times to retry acquiring the lock before giving up.
     * Default: 3.
     */
    attempts: number;
    /**
     * The amount of time to wait between retries (in ms)
     * Default: 0.1.
     */
    delay: number;
};
type LockAcquireConfig = {
    /**
     * The amount of time to hold the lock for (in ms).
     * Default: 10000 ms.
     */
    lease?: number;
    /**
     * The config for retrying to acquire the lock.
     */
    retry?: RetryConfig;
    /**
     * The uuid to be used for the lock.
     */
    uuid?: string;
};
type LockConfig = {
    /**
     * Upstash Redis client instance for locking operations.
     */
    redis: Redis;
    /**
     * Unique identifier associated with the lock.
     */
    id: string;
    /**
     * Duration (in ms) for which the lock should be held.
     */
    lease: number;
    /**
     * A unique value assigned when the lock is acquired.
     * It's set to null if the lock isn't successfully acquired.
     */
    UUID: string | null;
    /**
     * The config for retrying to acquire the lock.
     */
    retry: RetryConfig;
};
type LockCreateConfig = {
    /**
     * Unique identifier associated with the lock.
     */
    id: string;
    /**
     * Upstash Redis client instance for locking operations.
     */
    redis: Redis;
    /**
     * Duration (in ms) for which the lock should be held.
     */
    lease?: number;
    /**
     * The config for retrying to acquire the lock.
     */
    retry?: RetryConfig;
};
type LockStatus = "ACQUIRED" | "FREE";
type DebounceConfig = {
    /**
     * Upstash Redis client instance for locking operations.
     */
    redis: Redis;
    /**
     * Unique identifier associated with the lock.
     */
    id: string;
    /**
     * Duration (in ms) for which to wait before executing the callback.
     */
    wait: number;
    /**
     * The callback function to execute after the wait time.
     */
    callback: (...args: any[]) => any;
};

declare class Lock {
    private readonly config;
    private readonly DEFAULT_LEASE_MS;
    private readonly DEFAULT_RETRY_ATTEMPTS;
    private readonly DEFAULT_RETRY_DELAY_MS;
    constructor(config: LockCreateConfig);
    /**
     * Tries to acquire a lock with the given configuration.
     * If initially unsuccessful, the method will retry based on the provided retry configuration.
     *
     * @param config - Optional configuration for the lock acquisition to override the constructor config.
     * @returns {Promise<boolean>} True if the lock was acquired, otherwise false.
     */
    acquire(acquireConfig?: LockAcquireConfig): Promise<boolean>;
    /**
     * Safely releases the lock ensuring the UUID matches.
     * This operation utilizes a Lua script to interact with Redis and
     * guarantees atomicity of the unlock operation.
     * @returns {Promise<boolean>} True if the lock was released, otherwise false.
     */
    release(): Promise<boolean>;
    /**
     * Extends the duration for which the lock is held by a given amount of milliseconds.
     * @param amt - The number of milliseconds by which the lock duration should be extended.
     * @returns {Promise<boolean>} True if the lock duration was extended, otherwise false.
     */
    extend(amt: number): Promise<boolean>;
    get id(): string;
    /**
     * Gets the status of the lock, ie: ACQUIRED or FREE.
     * @returns {Promise<LockStatus>} The status of the lock.
     */
    getStatus(): Promise<LockStatus>;
}

export { DebounceConfig, Lock, LockAcquireConfig, LockConfig, LockCreateConfig, LockStatus, RetryConfig };
