/**
 * Queue Extensions - Backward Compatible Extensions
 * Extends existing Queue functionality without breaking changes
 */
import { Logger } from '../../config/logger.js';
import { createValidationError } from '../../exceptions/ZintrustError.js';
import { ZintrustLang } from '../../lang/lang.js';
import { createAdvancedQueue } from './AdvancedQueue.js';
import { createDeduplicationBuilder } from './DeduplicationBuilder.js';
import { createLockProvider, registerLockProvider } from './LockProvider.js';
import { Queue } from './Queue.js';
let advancedQueueRef = null;
/**
 * Extend existing Queue with advanced capabilities
 * This provides a migration path for existing code
 */
export function extendQueue(config) {
    try {
        const advancedQueue = createAdvancedQueue(config);
        advancedQueueRef = advancedQueue;
        Logger.info(`Queue extended with advanced capabilities`, { queueName: config.name });
    }
    catch (error) {
        Logger.error(`Failed to extend queue with advanced capabilities`, { error });
        throw error;
    }
}
/**
 * Enhanced enqueue method that supports advanced options
 * This can be used as a drop-in replacement for Queue.enqueue
 */
export async function enqueueAdvanced(name, payload, options = {}) {
    if (advancedQueueRef === null) {
        Logger.warn(`Advanced queue not initialized, falling back to standard enqueue`);
        const getQueue = await Queue?.enqueue(name, payload);
        return getQueue ?? '';
    }
    return advancedQueueRef.enqueue(name, payload, options);
}
/**
 * Initialize default lock providers
 */
export function initializeDefaultLockProviders() {
    // Register memory lock provider for sync driver
    registerLockProvider(ZintrustLang.MEMORY, createLockProvider({
        type: ZintrustLang.MEMORY,
        prefix: ZintrustLang.ZINTRUST_LOCKS_PREFIX,
        defaultTtl: ZintrustLang.ZINTRUST_LOCKS_TTL,
    }));
    // Register Redis lock provider if Redis is available
    try {
        const redisConfig = {
            type: ZintrustLang.REDIS,
            prefix: ZintrustLang.ZINTRUST_LOCKS_PREFIX,
            defaultTtl: ZintrustLang.ZINTRUST_LOCKS_TTL,
        };
        registerLockProvider('redis', createLockProvider(redisConfig));
        Logger.info(`Redis lock provider registered`);
    }
    catch (error) {
        Logger.warn(`Redis lock provider registration failed, using memory provider`, { error });
    }
}
/**
 * Get deduplication builder instance
 */
export function getDeduplicationBuilder() {
    return createDeduplicationBuilder();
}
/**
 * Queue utilities for lock management
 */
export const QueueLocks = {
    /**
     * Release a lock by key
     */
    async release(key) {
        if (advancedQueueRef !== null) {
            return advancedQueueRef.releaseLock(key);
        }
        throw createValidationError('Advanced queue not initialized. Call extendQueue() first.');
    },
    /**
     * Extend a lock's TTL
     */
    async extend(key, ttl) {
        if (advancedQueueRef !== null) {
            return advancedQueueRef.extendLock(key, ttl);
        }
        throw createValidationError('Advanced queue not initialized. Call extendQueue() first.');
    },
    /**
     * Check lock status
     */
    async status(key) {
        const { getLockProvider } = await import('../../tools/queue/LockProvider.js');
        const lockProvider = getLockProvider(ZintrustLang.MEMORY);
        if (lockProvider !== undefined) {
            const status = await lockProvider.status(key);
            return status.exists;
        }
        return false;
    },
};
/**
 * Migration helpers for existing queue code
 */
export const MigrationHelpers = {
    /**
     * Convert existing job options to advanced options
     */
    toAdvancedOptions(existingOptions, uniqueId) {
        return {
            ...existingOptions,
            ...(uniqueId !== null && uniqueId !== undefined && uniqueId !== '' && { uniqueId }),
        };
    },
    /**
     * Add deduplication to existing job patterns
     */
    withDeduplication(existingOptions, deduplicationId, ttl) {
        return {
            ...existingOptions,
            deduplication: createDeduplicationBuilder()
                .id(deduplicationId)
                .expireAfter(ttl ?? ZintrustLang.ZINTRUST_LOCKS_TTL)
                .build(),
        };
    },
};
