/*!
* @Author: richen
* @Date: 2026-04-24 16:20:40
* @License: BSD (3-Clause)
* @Copyright (c) - <richenlin(at)gmail.com>
* @HomePage: https://koatty.org/
*/
import { Cluster } from 'ioredis';
import { Koatty } from 'koatty_core';
import { Lock } from '@sesamecare-oss/redlock';
import Redis from 'ioredis';
import type { Settings } from '@sesamecare-oss/redlock';

/**
 * Base Redis configuration
 */
declare interface BaseRedisConfig {
    mode?: RedisMode;
    host?: string;
    port?: number;
    password?: string;
    db?: number;
    keyPrefix?: string;
    connectTimeout?: number;
    commandTimeout?: number;
    maxRetriesPerRequest?: number;
}

/**
 * Abstract distributed lock interface
 * Allows for different lock implementations (RedLock, Zookeeper, etc.)
 */
export declare interface IDistributedLock {
    /**
     * Initialize the lock system
     */
    initialize(): Promise<void>;
    /**
     * Acquire a distributed lock
     * @param resources - Resource identifiers
     * @param ttl - Time to live in milliseconds
     */
    acquire(resources: string[], ttl: number): Promise<Lock>;
    /**
     * Release a lock
     * @param lock - Lock instance
     */
    release(lock: Lock): Promise<void>;
    /**
     * Extend lock TTL
     * @param lock - Lock instance
     * @param ttl - New TTL in milliseconds
     */
    extend(lock: Lock, ttl: number): Promise<Lock>;
    /**
     * Check if the lock system is ready
     */
    isReady(): boolean;
    /**
     * Get current configuration
     */
    getConfig(): any;
    /**
     * Close and cleanup
     */
    close(): Promise<void>;
    /**
     * Health check
     */
    healthCheck(): Promise<{
        status: 'healthy' | 'unhealthy';
        details: Record<string, any>;
    }>;
}

/**
 * Lock configuration options
 */
export declare interface ILockOptions extends Partial<Settings> {
    lockTimeOut?: number;
    clockDriftFactor?: number;
    maxRetries?: number;
    retryDelayMs?: number;
    redisConfig?: RedisConfig;
}

/**
 * Abstract Redis client interface
 * Provides unified interface for different Redis implementations
 */
export declare interface IRedisClient {
    /**
     * Get connection status
     */
    readonly status: string;
    /**
     * Execute Redis command
     * @param command - Command name
     * @param args - Command arguments
     */
    call(command: string, ...args: any[]): Promise<any>;
    /**
     * Set a key-value pair
     * @param key - Key name
     * @param value - Value
     * @param mode - Optional mode (e.g., 'EX' for expiration)
     * @param duration - Optional duration in seconds
     */
    set(key: string, value: string | Buffer, mode?: string, duration?: number): Promise<'OK' | null>;
    /**
     * Get value by key
     * @param key - Key name
     */
    get(key: string): Promise<string | null>;
    /**
     * Delete one or more keys
     * @param keys - Key names
     */
    del(...keys: string[]): Promise<number>;
    /**
     * Check if key exists
     * @param key - Key name
     */
    exists(key: string): Promise<number>;
    /**
     * Evaluate Lua script
     * @param script - Lua script
     * @param numKeys - Number of keys
     * @param args - Script arguments
     */
    eval(script: string, numKeys: number, ...args: any[]): Promise<any>;
    /**
     * Close the connection
     */
    quit(): Promise<'OK'>;
    /**
     * Disconnect immediately
     */
    disconnect(): void;
}

/**
 * @param options - The options for the scheduled job
 * @param app - The Koatty application instance
 */
export declare function KoattyScheduled(options: ScheduledOptions, app: Koatty): Promise<void>;

/**
 * Redis client wrapper that implements IRedisClient interface
 * Wraps ioredis client to provide unified interface
 */
export declare class RedisClientAdapter implements IRedisClient {
    constructor(client: Redis | Cluster);
    get status(): string;
    call(command: string, ...args: any[]): Promise<any>;
    set(key: string, value: string | Buffer, mode?: string, duration?: number): Promise<'OK' | null>;
    get(key: string): Promise<string | null>;
    del(...keys: string[]): Promise<number>;
    exists(key: string): Promise<number>;
    eval(script: string, numKeys: number, ...args: any[]): Promise<any>;
    quit(): Promise<'OK'>;
    disconnect(): void;
    /**
     * Get underlying Redis/Cluster instance
     * Used for RedLock initialization
     */
    getClient(): Redis | Cluster;
}

/**
 * Cluster configuration
 */
export declare interface RedisClusterConfig extends BaseRedisConfig {
    mode: RedisMode.CLUSTER;
    nodes: Array<{
        host: string;
        port: number;
    }>;
    redisOptions?: {
        password?: string;
        db?: number;
    };
}

/**
 * Union type for all Redis configurations
 */
export declare type RedisConfig = RedisStandaloneConfig | RedisSentinelConfig | RedisClusterConfig;

/**
 * Redis client factory
 * Creates appropriate Redis client based on configuration
 */
export declare class RedisFactory {
    /**
     * Create Redis client based on configuration mode
     * @param config - Redis configuration
     * @returns Redis client adapter
     */
    static createClient(config: RedisConfig): RedisClientAdapter;
    /**
     * Create standalone Redis client
     * @param config - Standalone configuration
     */
    /**
     * Create sentinel Redis client
     * @param config - Sentinel configuration
     */
    /**
     * Create cluster Redis client
     * @param config - Cluster configuration
     */
    /**
     * Validate Redis configuration
     * @param config - Redis configuration to validate
     */
    static validateConfig(config: RedisConfig): void;
}

/**
 * Redis connection mode
 */
export declare enum RedisMode {
    STANDALONE = "standalone",// 单机模式
    SENTINEL = "sentinel",// 哨兵模式
    CLUSTER = "cluster"
}

/**
 * Sentinel configuration
 */
export declare interface RedisSentinelConfig extends BaseRedisConfig {
    mode: RedisMode.SENTINEL;
    sentinels: Array<{
        host: string;
        port: number;
    }>;
    name: string;
    sentinelPassword?: string;
}

/**
 * Standalone configuration
 */
export declare interface RedisStandaloneConfig extends BaseRedisConfig {
    mode?: RedisMode.STANDALONE;
    host: string;
    port: number;
}

/**
 * Redis-based distributed lock decorator
 *
 * @export
 * @param {string} [name] - The locker name. If name is duplicated, lock sharing contention will result.
 *                          If not provided, a unique name will be auto-generated using method name + random suffix.
 *                          IMPORTANT: Auto-generated names are unique per method deployment and not predictable.
 * @param {RedLockMethodOptions} [options] - Lock configuration options for this method
 *
 * @returns {MethodDecorator}
 * @throws {Error} When decorator is used on wrong class type or invalid configuration
 *
 * @example
 * ```typescript
 * class UserService {
 *   @RedLock('user_update_lock', { lockTimeOut: 5000, maxRetries: 2 })
 *   async updateUser(id: string, data: any) {
 *     // This method will be protected by a distributed lock with predictable name
 *   }
 *
 *   @RedLock() // Auto-generated unique name like "deleteUser_abc123_xyz789"
 *   async deleteUser(id: string) {
 *     // This method will be protected by a distributed lock with auto-generated unique name
 *   }
 * }
 * ```
 */
export declare function RedLock(lockName?: string, options?: RedLockMethodOptions): (...args: any[]) => any;

/**
 * RedLock distributed lock manager
 * Integrated with koatty IOC container
 * Implements singleton pattern for safe instance management
 * Implements IDistributedLock interface for abstraction
 */
export declare class RedLocker implements IDistributedLock {
    /**
     * Register RedLocker in IOC container
     * @private
     */
    /**
     * Get RedLocker singleton instance with thread-safe initialization
     * @static
     * @param options - RedLock configuration options (only used for first initialization)
     * @returns RedLocker singleton instance
     */
    static getInstance(options?: RedLockOptions): RedLocker;
    /**
     * Reset singleton instance (主要用于测试)
     * @static
     */
    static resetInstance(): void;
    /**
     * Initialize RedLock with Redis connection
     * Uses cached promise to avoid duplicate initialization
     * @private
     */
    initialize(): Promise<void>;
    /**
     * 执行实际的初始化操作
     * @private
     */
    /**
     * Acquire a distributed lock
     * @param resources - Resource identifiers to lock
     * @param ttl - Time to live in milliseconds
     * @returns Promise<Lock>
     */
    acquire(resources: string[], ttl?: number): Promise<Lock>;
    /**
     * Release a lock
     * @param lock - Lock instance to release
     */
    release(lock: Lock): Promise<void>;
    /**
     * Extend a lock's TTL
     * @param lock - Lock instance to extend
     * @param ttl - New TTL in milliseconds
     * @returns Extended lock
     */
    extend(lock: Lock, ttl: number): Promise<Lock>;
    /**
     * Check if RedLocker is initialized
     * @returns true if initialized, false otherwise
     */
    isReady(): boolean;
    /**
     * Get current configuration
     * @returns Current RedLock configuration
     */
    getConfig(): RedLockOptions;
    /**
     * Update configuration (requires reinitialization)
     * @param options - New RedLock options
     */
    updateConfig(options?: Partial<RedLockOptions>): void;
    /**
     * Close Redis connection and cleanup
     */
    close(): Promise<void>;
    /**
     * Get container registration status
     * @returns Registration information
     */
    getContainerInfo(): {
        registered: boolean;
        identifier: string;
    };
    /**
     * Health check for RedLocker
     * @returns Health status
     */
    healthCheck(): Promise<{
        status: 'healthy' | 'unhealthy';
        details: Record<string, any>;
    }>;
}

/**
 * RedLock method-level options (excluding Redis connection config)
 */
declare interface RedLockMethodOptions {
    lockTimeOut?: number;
    clockDriftFactor?: number;
    maxRetries?: number;
    retryDelayMs?: number;
}

/**
 * Configuration options for RedLock
 * @deprecated Use ILockOptions from interface instead
 */
export declare interface RedLockOptions extends ILockOptions {
    redisConfig?: RedisConfig;
}

/**
 * Schedule task decorator with optimized preprocessing
 *
 * @export
 * @param {string} cron - Cron expression for task scheduling
 * @param {string} [timezone='Asia/Beijing'] - Timezone for the schedule
 *
 * Cron expression format:
 * * Seconds: 0-59
 * * Minutes: 0-59
 * * Hours: 0-23
 * * Day of Month: 1-31
 * * Months: 1-12 (Jan-Dec)
 * * Day of Week: 1-7 (Sun-Sat)
 *
 * @returns {MethodDecorator}
 * @throws {Error} When cron expression is invalid or decorator is used on wrong class type
 */
export declare function Scheduled(cron: string, timezone?: string): (...args: any[]) => any;

/**
 * Scheduled global options interface
 */
declare interface ScheduledOptions extends RedLockOptions {
    timezone?: string;
}

/**
 * @deprecated Use RedLock instead. This will be removed in v3.0.0
 */
export declare const SchedulerLock: typeof RedLock;

export { }
