"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const index_js_1 = require("./index.js");
(0, vitest_1.describe)('PriorityQueue', () => {
    let queue;
    (0, vitest_1.beforeEach)(() => {
        queue = new index_js_1.PriorityQueue();
    });
    (0, vitest_1.describe)('add', () => {
        (0, vitest_1.it)('should add an item with correct priority based on type', async () => {
            const item = await queue.add('stars_payment', 'char-1', { amount: 100 });
            (0, vitest_1.expect)(item.type).toBe('stars_payment');
            (0, vitest_1.expect)(item.priority).toBe(1);
            (0, vitest_1.expect)(item.status).toBe('pending');
            (0, vitest_1.expect)(item.characterId).toBe('char-1');
            (0, vitest_1.expect)(item.retryCount).toBe(0);
            (0, vitest_1.expect)(item.maxRetries).toBe(3);
        });
        (0, vitest_1.it)('should assign correct priorities for all types', async () => {
            const stars = await queue.add('stars_payment', 'c1', {});
            const chat = await queue.add('chat_response', 'c1', {});
            const image = await queue.add('image_generation', 'c1', {});
            const quality = await queue.add('quality_check', 'c1', {});
            const publish = await queue.add('channel_publish', 'c1', {});
            const translate = await queue.add('translation', 'c1', {});
            (0, vitest_1.expect)(stars.priority).toBe(1);
            (0, vitest_1.expect)(chat.priority).toBe(2);
            (0, vitest_1.expect)(image.priority).toBe(3);
            (0, vitest_1.expect)(quality.priority).toBe(4);
            (0, vitest_1.expect)(publish.priority).toBe(5);
            (0, vitest_1.expect)(translate.priority).toBe(5);
        });
        (0, vitest_1.it)('should use custom maxRetries when provided', async () => {
            const item = await queue.add('chat_response', 'c1', {}, 5);
            (0, vitest_1.expect)(item.maxRetries).toBe(5);
        });
    });
    (0, vitest_1.describe)('dequeue', () => {
        (0, vitest_1.it)('should return undefined when queue is empty', () => {
            (0, vitest_1.expect)(queue.dequeue()).toBeUndefined();
        });
        (0, vitest_1.it)('should dequeue highest priority item first', async () => {
            await queue.add('channel_publish', 'c1', { order: 1 });
            await queue.add('stars_payment', 'c1', { order: 2 });
            await queue.add('chat_response', 'c1', { order: 3 });
            const item = queue.dequeue();
            (0, vitest_1.expect)(item?.type).toBe('stars_payment');
            (0, vitest_1.expect)(item?.status).toBe('processing');
        });
        (0, vitest_1.it)('should follow FIFO for same priority items', async () => {
            const first = await queue.add('channel_publish', 'c1', { order: 'first' });
            const second = await queue.add('translation', 'c1', { order: 'second' });
            const dequeued = queue.dequeue();
            (0, vitest_1.expect)(dequeued?.id).toBe(first.id);
        });
        (0, vitest_1.it)('should skip non-pending items', async () => {
            const item1 = await queue.add('stars_payment', 'c1', {});
            await queue.add('chat_response', 'c1', {});
            // Dequeue first item (marks it as processing)
            queue.dequeue();
            // Next dequeue should get the chat_response
            const next = queue.dequeue();
            (0, vitest_1.expect)(next?.type).toBe('chat_response');
        });
    });
    (0, vitest_1.describe)('updateStatus', () => {
        (0, vitest_1.it)('should update item status', async () => {
            const item = await queue.add('chat_response', 'c1', {});
            const updated = await queue.updateStatus(item.id, 'completed');
            (0, vitest_1.expect)(updated?.status).toBe('completed');
        });
        (0, vitest_1.it)('should set error on failure', async () => {
            const item = await queue.add('chat_response', 'c1', {});
            const updated = await queue.updateStatus(item.id, 'failed', 'API timeout');
            (0, vitest_1.expect)(updated?.error).toBe('API timeout');
            (0, vitest_1.expect)(updated?.retryCount).toBe(1);
        });
        (0, vitest_1.it)('should return null for non-existent item', async () => {
            const result = await queue.updateStatus('non-existent', 'completed');
            (0, vitest_1.expect)(result).toBeNull();
        });
    });
    (0, vitest_1.describe)('getById', () => {
        (0, vitest_1.it)('should find item by id', async () => {
            const item = await queue.add('chat_response', 'c1', { data: 'test' });
            const found = queue.getById(item.id);
            (0, vitest_1.expect)(found?.id).toBe(item.id);
        });
        (0, vitest_1.it)('should return undefined for non-existent id', () => {
            (0, vitest_1.expect)(queue.getById('missing')).toBeUndefined();
        });
    });
    (0, vitest_1.describe)('getPending / getFailed / getAll', () => {
        (0, vitest_1.it)('should filter items by status', async () => {
            const item1 = await queue.add('chat_response', 'c1', {});
            const item2 = await queue.add('image_generation', 'c1', {});
            await queue.updateStatus(item2.id, 'failed', 'error');
            (0, vitest_1.expect)(queue.getPending()).toHaveLength(1);
            (0, vitest_1.expect)(queue.getFailed()).toHaveLength(1);
            (0, vitest_1.expect)(queue.getAll()).toHaveLength(2);
        });
    });
    (0, vitest_1.describe)('getStats', () => {
        (0, vitest_1.it)('should return correct counts', async () => {
            await queue.add('chat_response', 'c1', {});
            await queue.add('image_generation', 'c1', {});
            const item3 = await queue.add('quality_check', 'c1', {});
            await queue.updateStatus(item3.id, 'failed', 'err');
            const stats = queue.getStats();
            (0, vitest_1.expect)(stats.pending).toBe(2);
            (0, vitest_1.expect)(stats.failed).toBe(1);
            (0, vitest_1.expect)(stats.processing).toBe(0);
            (0, vitest_1.expect)(stats.completed).toBe(0);
        });
    });
    (0, vitest_1.describe)('retry', () => {
        (0, vitest_1.it)('should re-queue a failed item', async () => {
            const item = await queue.add('chat_response', 'c1', {});
            await queue.updateStatus(item.id, 'failed', 'timeout');
            const result = await queue.retry(item.id);
            (0, vitest_1.expect)(result).toBe(true);
            const retried = queue.getById(item.id);
            (0, vitest_1.expect)(retried?.status).toBe('pending');
            (0, vitest_1.expect)(retried?.error).toBeUndefined();
        });
        (0, vitest_1.it)('should refuse retry when maxRetries exceeded', async () => {
            const item = await queue.add('chat_response', 'c1', {}, 1);
            await queue.updateStatus(item.id, 'failed', 'err');
            const result = await queue.retry(item.id);
            (0, vitest_1.expect)(result).toBe(false);
        });
        (0, vitest_1.it)('should refuse retry for non-failed items', async () => {
            const item = await queue.add('chat_response', 'c1', {});
            const result = await queue.retry(item.id);
            (0, vitest_1.expect)(result).toBe(false);
        });
    });
    (0, vitest_1.describe)('loadItems', () => {
        (0, vitest_1.it)('should load and sort items', () => {
            const items = [
                {
                    id: '1', type: 'channel_publish', priority: 5, status: 'pending',
                    characterId: 'c1', payload: {}, retryCount: 0, maxRetries: 3,
                    createdAt: '2024-01-01T00:00:00Z', updatedAt: '2024-01-01T00:00:00Z',
                },
                {
                    id: '2', type: 'stars_payment', priority: 1, status: 'pending',
                    characterId: 'c1', payload: {}, retryCount: 0, maxRetries: 3,
                    createdAt: '2024-01-01T00:00:01Z', updatedAt: '2024-01-01T00:00:01Z',
                },
            ];
            queue.loadItems(items);
            const dequeued = queue.dequeue();
            (0, vitest_1.expect)(dequeued?.id).toBe('2'); // stars_payment has higher priority
        });
    });
    (0, vitest_1.describe)('processNext (via processor)', () => {
        (0, vitest_1.it)('should auto-process items when processor is set', async () => {
            const processed = [];
            queue.setProcessor(async (item) => {
                processed.push(item.id);
            });
            const item = await queue.add('chat_response', 'c1', {});
            // Wait for async processing
            await new Promise(resolve => setTimeout(resolve, 50));
            (0, vitest_1.expect)(processed).toContain(item.id);
            (0, vitest_1.expect)(queue.getById(item.id)?.status).toBe('completed');
        });
        (0, vitest_1.it)('should handle processor errors and mark as failed', async () => {
            queue.setProcessor(async () => {
                throw new Error('Processing failed');
            });
            const item = await queue.add('chat_response', 'c1', {}, 0);
            await new Promise(resolve => setTimeout(resolve, 50));
            const updated = queue.getById(item.id);
            (0, vitest_1.expect)(updated?.status).toBe('failed');
            (0, vitest_1.expect)(updated?.error).toBe('Processing failed');
        });
    });
    (0, vitest_1.describe)('persist callback', () => {
        (0, vitest_1.it)('should call onPersist when items change', async () => {
            const persistedItems = [];
            queue.setOnPersist(async (items) => {
                persistedItems.push(items);
            });
            await queue.add('chat_response', 'c1', {});
            (0, vitest_1.expect)(persistedItems.length).toBeGreaterThan(0);
        });
    });
});
//# sourceMappingURL=index.test.js.map