import { RedisClientType } from '@redis/client';
import { RedisClusterCacheAdapter } from '../helpers/redisClusterAdapter.cjs';
import { CacheHandlerValue } from './cache-handler.types.cjs';
import 'next/dist/server/lib/incremental-cache';
import 'next/dist/server/lib/incremental-cache/file-system-cache';

/**
 * Pluggable wire-format codec for Redis string values (JSON, compression, encryption, etc.).
 * Default behavior is JSON.stringify / JSON.parse (see `jsonCacheValueSerializer` export).
 *
 * Both methods may return a `Promise`, enabling non-blocking async codecs such as
 * stream-based compression (`zlib.brotliCompress`) or encryption (`crypto.subtle`).
 * Synchronous implementations continue to work unchanged — `await` on a plain value is a no-op.
 */
type CacheValueSerializer = {
    serialize(value: CacheHandlerValue): string | Promise<string>;
    deserialize(stored: string): CacheHandlerValue | null | Promise<CacheHandlerValue | null>;
};
type RedisCompliantCachedRouteValue = {
    kind: "APP_ROUTE";
    body: string | undefined;
};
type RedisCompliantCachedAppPageValue = {
    kind: "APP_PAGE";
    rscData: string | undefined;
    segmentData: Record<string, string> | undefined;
};
type CreateRedisStringsHandlerOptions<T = RedisClientType | RedisClusterCacheAdapter> = {
    /**
     * The Redis client instance.
     */
    client: T;
    /**
     * Optional. Prefix for all keys, useful for namespacing.
     *
     * @default '' // empty string
     */
    keyPrefix?: string;
    /**
     * Optional. Timeout in milliseconds for Redis operations.
     *
     * @default 5000 // 5000 ms
     *
     * @remarks
     * To disable timeout of Redis operations, set this option to 0.
     */
    timeoutMs?: number;
    /**
     * Optional. The number of tags in a single query retrieved from Redis when scanning or searching for tags.
     *
     * @default 10_000 // 10,000 tags
     *
     * @remarks
     * You can adjust this value to optimize the number of commands sent to Redis when scanning or searching for tags.
     * A higher value will reduce the number of commands sent to Redis,
     * but it will also increase the amount of data transferred over the network.
     * Redis uses TCP and typically has 65,535 bytes as the maximum size of a packet (it can be lower depending on MTU).
     */
    revalidateTagQuerySize?: number;
    /**
     * Key for storing cache tags.
     *
     * @default '__sharedTags__'
     */
    sharedTagsKey?: string;
    /**
     * Key for storing cache tags TTL.
     *
     * @default '__sharedTagsTtl__'
     */
    sharedTagsTtlKey?: string;
    /**
     * Determines the expiration strategy for cache keys.
     *
     * - `'EXAT'`: Uses the `EXAT` option of the `SET` command to set expiration time.
     * - `'EXPIREAT'`: Uses the `EXPIREAT` command to set expiration time.
     *
     * By default, it uses `'EXPIREAT'` for compatibility with older versions.
     *
     * @default 'EXPIREAT'
     */
    keyExpirationStrategy?: "EXAT" | "EXPIREAT";
    /**
     * Optional codec for values stored in Redis (`SET`/`GET`).
     * Implement compression, encryption, or custom formats in your app; this package stays dependency-free.
     *
     * Both `serialize` and `deserialize` may return a `Promise`, enabling non-blocking async codecs
     * (e.g. `zlib.brotliCompress` / `zlib.brotliDecompress`) that avoid blocking the Node.js event loop.
     * Synchronous implementations continue to work unchanged.
     *
     * @default JSON.stringify / JSON.parse (same as previous releases)
     */
    valueSerializer?: CacheValueSerializer;
};

export type { CacheValueSerializer, CreateRedisStringsHandlerOptions, RedisCompliantCachedAppPageValue, RedisCompliantCachedRouteValue };
