import * as _lock_dev_core from '@lock-dev/core';
import { SecurityContext } from '@lock-dev/core';

type RateLimitStrategy = 'fixed-window' | 'sliding-window' | 'token-bucket' | 'leaky-bucket' | 'adaptive';
type RateLimitStorage = 'memory' | 'redis' | 'upstash';
type GeoProvider = 'ipapi' | 'maxmind';
declare enum RateLimitEventType {
    RATE_LIMITED = "rate_limited",
    RATE_LIMIT_WARNING = "rate_limit_warning",
    RATE_LIMIT_ADAPTIVE_ESCALATION = "rate_limit_adaptive_escalation",
    DDOS_PROTECTION_TRIGGERED = "ddos_protection_triggered"
}
interface RateLimitKey {
    identifier: string;
    resource?: string;
    country?: string;
}
interface RateLimitRecord {
    count: number;
    firstRequest: number;
    lastRequest: number;
    history?: number[];
    tokens?: number;
    warningIssued?: boolean;
    ddosScore?: number;
}
interface RateLimitResult {
    passed: boolean;
    remaining?: number;
    limit?: number;
    retry?: number;
    reason?: string;
    data?: any;
}
interface RateLimitConfig {
    limit: number;
    windowMs: number;
    strategy?: RateLimitStrategy;
    storage?: RateLimitStorage;
    resources?: {
        [resource: string]: {
            limit: number;
            windowMs: number;
        };
    };
    countryLimits?: {
        [country: string]: {
            limit: number;
            windowMs: number;
        };
    };
    geoProvider?: {
        type: GeoProvider;
        dbPath?: string;
        cacheSize?: number;
        cacheTtl?: number;
    };
    adaptive?: {
        enabled: boolean;
        thresholds: {
            normal: number;
            elevated: number;
            high: number;
            extreme: number;
        };
        escalationPeriod: number;
        cooldownPeriod: number;
    };
    ddosPrevention?: {
        enabled: boolean;
        requestRateThreshold: number;
        burstThreshold: number;
        banDurationMs: number;
        ipReputation?: boolean;
        behavioralAnalysis?: boolean;
        challengeMode?: boolean;
    };
    headers?: boolean;
    standardHeaders?: boolean;
    headerLimit?: string;
    headerRemaining?: string;
    headerReset?: string;
    statusCode?: number;
    message?: string;
    ipHeaders?: string[];
    useRemoteAddress?: boolean;
    redis?: {
        url?: string;
        host?: string;
        port?: number;
        password?: string;
        username?: string;
        database?: number;
        keyPrefix?: string;
    };
    upstash?: {
        url: string;
        token: string;
        keyPrefix?: string;
    };
    memoryOptions?: {
        max: number;
        ttl: number;
    };
    skipFunction?: (context: SecurityContext) => boolean | Promise<boolean>;
    keyGenerator?: (context: SecurityContext) => string | Promise<string>;
    handler?: (context: SecurityContext, info: any) => void | Promise<void>;
}
interface RateLimitStore {
    init(): Promise<void>;
    get(key: string): Promise<RateLimitRecord | null>;
    set(key: string, value: RateLimitRecord): Promise<void>;
    increment(key: string, value?: number): Promise<RateLimitRecord>;
    reset(key: string): Promise<void>;
    close(): Promise<void>;
    addToHistory?(key: string, timestamp: number): Promise<void>;
    getWindowHistory?(key: string, startTime: number): Promise<number[]>;
}
interface GeoLocationProvider {
    lookupCountry(ip: string): Promise<string | null>;
}

/**
 * Fixed In-memory store implementation for rate limiting.
 * This implementation uses an LRU (Least Recently Used) cache to manage rate limit records,
 * providing methods to initialize, get, set, increment, reset, and manage the history of requests.
 *
 * @class MemoryStore
 * @implements {RateLimitStore}
 */
declare class MemoryStore implements RateLimitStore {
    private cache;
    /**
     * Creates an instance of MemoryStore.
     *
     * @param {Object} options - Configuration options for the store.
     * @param {number} options.max - Maximum number of items the cache can hold.
     * @param {number} options.ttl - Time-to-live for each cache entry in milliseconds.
     */
    constructor(options: {
        max: number;
        ttl: number;
    });
    /**
     * Initializes the MemoryStore.
     * This method is called to set up the store and can be used to perform any asynchronous initialization tasks.
     *
     * @returns {Promise<void>} A promise that resolves when the store is initialized.
     */
    init(): Promise<void>;
    /**
     * Retrieves a rate limit record from the store for the given key.
     *
     * @param {string} key - The key identifying the rate limit record.
     * @returns {Promise<RateLimitRecord | null>} A promise that resolves with the record if found, or null if not.
     */
    get(key: string): Promise<RateLimitRecord | null>;
    /**
     * Stores a rate limit record in the store under the given key.
     *
     * @param {string} key - The key under which to store the record.
     * @param {RateLimitRecord} value - The rate limit record to store.
     * @returns {Promise<void>} A promise that resolves once the record is stored.
     */
    set(key: string, value: RateLimitRecord): Promise<void>;
    /**
     * Increments the rate limit counter for a given key.
     * If the key does not exist, a new record is created.
     * The function updates the record's count, lastRequest timestamp, and history.
     *
     * @param {string} key - The key identifying the rate limit record.
     * @param {number} [value=1] - The value to increment the counter by.
     * @returns {Promise<RateLimitRecord>} A promise that resolves with the updated rate limit record.
     */
    increment(key: string, value?: number): Promise<RateLimitRecord>;
    /**
     * Resets the rate limit record for a given key by removing it from the store.
     *
     * @param {string} key - The key identifying the rate limit record to reset.
     * @returns {Promise<void>} A promise that resolves once the record is removed.
     */
    reset(key: string): Promise<void>;
    /**
     * Closes the store.
     * This method can be used to perform any necessary cleanup operations.
     *
     * @returns {Promise<void>} A promise that resolves when the store is closed.
     */
    close(): Promise<void>;
    /**
     * Adds a specific timestamp to the history of requests for a given key.
     * If the record exists, the timestamp is appended to its history.
     *
     * @param {string} key - The key identifying the rate limit record.
     * @param {number} timestamp - The timestamp to add to the record's history.
     * @returns {Promise<void>} A promise that resolves once the timestamp is added.
     */
    addToHistory(key: string, timestamp: number): Promise<void>;
    /**
     * Retrieves the history of timestamps for a given key, filtered to include only those
     * entries that occurred after a specified start time.
     *
     * @param {string} key - The key identifying the rate limit record.
     * @param {number} startTime - The start time (inclusive) for filtering the history.
     * @returns {Promise<number[]>} A promise that resolves with an array of timestamps from the history that meet the criteria.
     */
    getWindowHistory(key: string, startTime: number): Promise<number[]>;
}

declare class RedisStore implements RateLimitStore {
    private client;
    private keyPrefix;
    private config;
    constructor(config: RateLimitConfig);
    init(): Promise<void>;
    get(key: string): Promise<RateLimitRecord | null>;
    set(key: string, value: RateLimitRecord): Promise<void>;
    increment(key: string, value?: number): Promise<RateLimitRecord>;
    reset(key: string): Promise<void>;
    close(): Promise<void>;
    addToHistory(key: string, timestamp: number): Promise<void>;
    getWindowHistory(key: string, startTime: number): Promise<number[]>;
}

declare class UpstashStore implements RateLimitStore {
    private client;
    private keyPrefix;
    private config;
    constructor(config: RateLimitConfig);
    init(): Promise<void>;
    get(key: string): Promise<RateLimitRecord | null>;
    set(key: string, value: RateLimitRecord): Promise<void>;
    increment(key: string, value?: number): Promise<RateLimitRecord>;
    reset(key: string): Promise<void>;
    close(): Promise<void>;
    addToHistory(key: string, timestamp: number): Promise<void>;
    getWindowHistory(key: string, startTime: number): Promise<number[]>;
}

/**
 * Creates the appropriate storage implementation based on configuration
 * @param config Rate limiter configuration
 * @returns Initialized storage implementation
 */
declare function createStore(config: RateLimitConfig): Promise<RateLimitStore>;

/**
 * Fixed Window Rate Limit Strategy Implementation
 *
 * Algorithm Overview:
 * 1. Get the current timestamp.
 * 2. Retrieve the rate limit record for the given key from the store.
 * 3. If no record exists or the current time exceeds the window duration since the first request:
 *    - Reset the window by creating a new record with the current timestamp.
 *    - Set the counter to 1 and store the record.
 *    - Allow the request and return the remaining limit.
 * 4. Otherwise, if the record exists and the window is still valid:
 *    - Increment the record count.
 *    - Calculate the elapsed time and the remaining window duration.
 *    - If the incremented count exceeds the defined limit:
 *       - Deny the request, return rate-limited response with retry time.
 *    - Otherwise:
 *       - Allow the request and update the remaining limit.
 *
 * @class FixedWindowStrategy
 * @implements {RateLimitStrategyImplementation}
 */
declare class FixedWindowStrategy implements RateLimitStrategyImplementation {
    /**
     * Checks the rate limit for a given key and returns the result.
     *
     * @param {string} key - The unique key representing the request (often an IP or identifier).
     * @param {SecurityContext} context - The security context containing the request data.
     * @param {RateLimitConfig} config - The configuration object containing limit and window settings.
     * @param {RateLimitStore} store - The store instance to get, set, or increment the rate limit record.
     * @returns {Promise<RateLimitResult>} A promise that resolves with the rate limit result including status, remaining quota, limit, and retry time.
     */
    check(key: string, context: SecurityContext, config: RateLimitConfig, store: RateLimitStore): Promise<RateLimitResult>;
}

/**
 * Leaky Bucket rate limiting implementation.
 * Processes requests at a fixed outflow rate with a limited bucket capacity,
 * simulating a "leaky bucket" where excess requests are discarded or delayed.
 *
 * Algorithm Overview:
 * 1. Determine the outflow rate (i.e. the rate at which requests "leak" out of the bucket)
 *    by dividing the limit by the window duration (requests per millisecond).
 * 2. Retrieve the current rate limit record from the store using the provided key.
 * 3. If no record exists:
 *    - Initialize a new record with a count of 1 (representing the first request),
 *      and set both the firstRequest and lastRequest timestamps to the current time.
 *    - Store the new record and return a successful result with the remaining capacity.
 * 4. If a record exists:
 *    - Calculate the time elapsed since the last request.
 *    - Compute the number of leaked requests based on the outflow rate and time elapsed.
 *    - Update the bucket level by subtracting the leaked requests (ensuring it does not fall below 0).
 *    - If the updated level is below the bucket capacity:
 *      - Accept the current request by incrementing the bucket count,
 *      - Update the lastRequest timestamp, store the record, and return success with the remaining capacity.
 *    - If the updated level equals or exceeds the bucket capacity:
 *      - The bucket is full, so calculate the wait time required for the bucket to leak enough requests
 *        to accommodate one new request.
 *      - Update the lastRequest timestamp, store the record, and return a rate limited result
 *        with the appropriate retry time.
 *
 * @class LeakyBucketStrategy
 * @implements {RateLimitStrategyImplementation}
 */
declare class LeakyBucketStrategy implements RateLimitStrategyImplementation {
    check(key: string, context: SecurityContext, config: RateLimitConfig, store: RateLimitStore): Promise<RateLimitResult>;
}

/**
 * Sliding Window rate limiting implementation.
 * More accurate counting of requests in a rolling time window.
 *
 * Algorithm Overview:
 * 1. Obtain the current timestamp and compute the start of the sliding window (now - windowMs).
 * 2. Retrieve the current rate limit record from the store using the provided key.
 * 3. If no record exists:
 *    - Create a new record with:
 *      - count set to 1,
 *      - firstRequest and lastRequest set to the current timestamp,
 *      - history array initialized with the current timestamp.
 *    - Save the new record in the store and return a successful rate limit result.
 * 4. If a record exists:
 *    - Ensure the record has a history array.
 *    - Append the current timestamp to the history and update lastRequest.
 *    - Filter the history array to include only timestamps within the sliding window.
 *    - Update the record count based on the filtered history.
 *    - Save the updated record back to the store.
 * 5. Determine if the request count exceeds the configured limit:
 *    - If the count exceeds the limit, compute the retry time based on the oldest timestamp in the window,
 *      then return a failure response with the reason "RATE_LIMITED" and the computed retry time.
 *    - Otherwise, return a successful response including the remaining request count and the retry time.
 *
 * @class SlidingWindowStrategy
 * @implements {RateLimitStrategyImplementation}
 */
declare class SlidingWindowStrategy implements RateLimitStrategyImplementation {
    check(key: string, context: SecurityContext, config: RateLimitConfig, store: RateLimitStore): Promise<RateLimitResult>;
}

/**
 * Token Bucket rate limiting implementation.
 * Allows for bursts of traffic while maintaining an average rate.
 *
 * Algorithm Overview:
 * 1. Determine the refill rate in tokens per millisecond and the maximum tokens (bucket capacity)
 *    based on the configuration.
 * 2. Retrieve the current rate limit record for the given key from the store.
 * 3. If no record exists:
 *    - Initialize a new record with a full bucket (max tokens), consume one token for the current request,
 *      and save the record.
 *    - Return a successful rate limit result with the updated token count.
 * 4. If a record exists:
 *    - Calculate the number of tokens to refill based on the elapsed time since the last request.
 *    - Update the token count, ensuring it does not exceed the maximum capacity.
 *    - Attempt to consume a token:
 *      - If a token is available, deduct one token, update the request count and timestamp, then return success.
 *      - If no token is available, calculate the wait time required to generate one token,
 *        update the record, and return a failure result indicating rate limiting.
 *
 * @class TokenBucketStrategy
 * @implements {RateLimitStrategyImplementation}
 */
declare class TokenBucketStrategy implements RateLimitStrategyImplementation {
    check(key: string, context: SecurityContext, config: RateLimitConfig, store: RateLimitStore): Promise<RateLimitResult>;
}

/**
 * Adaptive rate limiting implementation.
 * Adjusts rate limits dynamically based on current traffic patterns and potential suspicious activity.
 *
 * Algorithm Overview:
 * 1. Check if adaptive rate limiting is enabled in the configuration; if not, fall back to the fixed window strategy.
 * 2. Retrieve the rate limit record from the store for the given key.
 *    - If no record exists, create a new record with the current timestamp and initialize the history.
 * 3. Add the current request timestamp to the record’s history.
 * 4. Calculate the number of requests within the sliding window by filtering the history based on the window duration.
 * 5. Compute the current request rate (requests per second).
 *
 * 6. Calculate burst behavior using standard deviation of request intervals:
 *    - Standard deviation (σ) measures how much the intervals between requests vary.
 *    - Formula: σ = sqrt(variance), where variance = (1/n) * Σ(xᵢ - μ)²
 *      - xᵢ = each interval between requests
 *      - μ = average interval = (Σxᵢ)/n
 *      - n = number of intervals
 *    - A lower standard deviation indicates that requests are arriving at a more uniform rate,
 *      which can be a sign of automated or bot traffic.
 *
 * 7. Based on predefined adaptive thresholds:
 *    - Adjust the effective rate limit dynamically (reduce the limit if request rate exceeds thresholds).
 *    - Set an escalation level indicating the severity (e.g., elevated, high, or extreme).
 * 8. Update the record with the current count and check if the dynamic limit is exceeded:
 *    - If exceeded, log an escalation event if appropriate, and return a rate-limited response including a retry time.
 *    - Otherwise, allow the request and return the remaining quota based on the dynamic limit.
 *
 * Importance of Standard Deviation in Adaptive Limiting:
 * Standard deviation is used here to detect burstiness or uniformity in request intervals.
 * - A low standard deviation relative to the mean interval (i.e., intervals are very consistent)
 *   may indicate automated or scripted traffic.
 * - This metric is combined with the overall request rate to decide if the limit should be lowered dynamically.
 *
 * @class AdaptiveStrategy
 * @implements {RateLimitStrategyImplementation}
 */
declare class AdaptiveStrategy implements RateLimitStrategyImplementation {
    check(key: string, context: SecurityContext, config: RateLimitConfig, store: RateLimitStore): Promise<RateLimitResult>;
}

interface RateLimitStrategyImplementation {
    check(key: string, context: SecurityContext, config: RateLimitConfig, store: RateLimitStore): Promise<RateLimitResult>;
}

/**
 * Creates the appropriate rate limit strategy implementation based on configuration.
 *
 * @param {RateLimitConfig} config - The rate limiter configuration object.
 * @returns {RateLimitStrategyImplementation} The strategy implementation instance.
 */
declare function createStrategy(config: RateLimitConfig): RateLimitStrategyImplementation;
/**
 * @class DDoSProtection
 */
declare class DDoSProtection {
    private config;
    private blacklist;
    private enabled;
    private requestRateThreshold;
    private burstThreshold;
    private banDurationMs;
    private windowMs;
    private readonly CRITICAL_THRESHOLD;
    private readonly HIGH_THRESHOLD;
    private readonly MEDIUM_THRESHOLD;
    private readonly LOW_THRESHOLD;
    /**
     * Creates an instance of DDoSProtection.
     */
    constructor(config: RateLimitConfig);
    /**
     * Fast check to determine if IP is a known threat
     * This is a quick first-pass filter before more expensive analysis
     */
    isKnownThreat(ip: string): {
        isThreat: boolean;
        level?: string;
        banDuration?: number;
    };
    /**
     * Optimized analysis algorithm for DDoS threat detection
     * Employs early exits and efficient calculations
     */
    analyze(key: string, context: SecurityContext, store: RateLimitStore): Promise<{
        isThreat: boolean;
        level: 'none' | 'low' | 'medium' | 'high' | 'critical';
        score: number;
        banDuration?: number;
    }>;
    /**
     * Optimized blacklist check with efficient expiration handling
     */
    isBlacklisted(ip: string): boolean;
    /**
     * Get approximate blacklist size
     */
    getBlacklistSize(): number;
    /**
     * Clear expired blacklist entries
     * Call periodically for memory management
     */
    cleanBlacklist(): number;
}

/**
 * Create a rate limiting security module
 * @param config Module configuration
 */
declare const rateLimit: (config?: Partial<RateLimitConfig> | undefined) => _lock_dev_core.SecurityModule;

export { AdaptiveStrategy, DDoSProtection, FixedWindowStrategy, type GeoLocationProvider, type GeoProvider, LeakyBucketStrategy, MemoryStore, type RateLimitConfig, RateLimitEventType, type RateLimitKey, type RateLimitRecord, type RateLimitResult, type RateLimitStorage, type RateLimitStore, type RateLimitStrategy, type RateLimitStrategyImplementation, RedisStore, SlidingWindowStrategy, TokenBucketStrategy, UpstashStore, createStore, createStrategy, rateLimit };
