"use strict";
/**
 * Critical Pagination Fix Test
 * Tests the new pagination functionality for context_search_all to prevent token overflow
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const database_1 = require("../../utils/database");
const repositories_1 = require("../../repositories");
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const uuid_1 = require("uuid");
describe('Pagination Critical Fix', () => {
    let dbManager;
    let repositories;
    let sessionId;
    let tempDbPath;
    let db;
    beforeEach(() => {
        tempDbPath = path.join(os.tmpdir(), `test-pagination-${Date.now()}.db`);
        dbManager = new database_1.DatabaseManager({
            filename: tempDbPath,
            maxSize: 10 * 1024 * 1024,
            walMode: true,
        });
        repositories = new repositories_1.RepositoryManager(dbManager);
        db = dbManager.getDatabase();
        // Create test session
        sessionId = (0, uuid_1.v4)();
        db.prepare('INSERT INTO sessions (id, name, description) VALUES (?, ?, ?)').run(sessionId, 'Pagination Test Session', 'Test session for pagination testing');
        // Add test data to test pagination
        for (let i = 1; i <= 50; i++) {
            db.prepare('INSERT INTO context_items (id, session_id, key, value, category, priority, size) VALUES (?, ?, ?, ?, ?, ?, ?)').run((0, uuid_1.v4)(), sessionId, `test_item_${i}`, `This is test item number ${i} with searchable content`, i % 2 === 0 ? 'task' : 'note', i % 3 === 0 ? 'high' : 'normal', 100 // size in bytes
            );
        }
    });
    afterEach(() => {
        dbManager.close();
        try {
            fs.unlinkSync(tempDbPath);
            fs.unlinkSync(`${tempDbPath}-wal`);
            fs.unlinkSync(`${tempDbPath}-shm`);
        }
        catch (_e) {
            // Ignore cleanup errors
        }
    });
    describe('searchAcrossSessionsEnhanced', () => {
        test('should implement default pagination (25 items)', () => {
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
            });
            expect(result.items).toHaveLength(25); // Default limit
            expect(result.totalCount).toBe(50);
            expect(result.pagination).toMatchObject({
                currentPage: 1,
                totalPages: 2,
                totalItems: 50,
                itemsPerPage: 25,
                hasNextPage: true,
                hasPreviousPage: false,
                nextOffset: 25,
                previousOffset: null,
            });
        });
        test('should handle custom pagination parameters', () => {
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                limit: 10,
                offset: 20,
            });
            expect(result.items).toHaveLength(10);
            expect(result.totalCount).toBe(50);
            expect(result.pagination.currentPage).toBe(3); // offset 20 / limit 10 + 1
            expect(result.pagination.totalPages).toBe(5); // 50 / 10
            expect(result.pagination.hasNextPage).toBe(true);
            expect(result.pagination.hasPreviousPage).toBe(true);
        });
        test('should enforce maximum limit of 100', () => {
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                limit: 500, // Should be capped at 100
            });
            expect(result.pagination.itemsPerPage).toBe(100); // Capped at maximum 100
            expect(result.items).toHaveLength(50); // But only 50 items available
        });
        test('should handle minimum limit of 1', () => {
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                limit: -5, // Should be set to 1
            });
            expect(result.pagination.itemsPerPage).toBe(1);
            expect(result.items).toHaveLength(1);
        });
        test('should handle invalid offset values', () => {
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                offset: -10, // Should be set to 0
            });
            expect(result.pagination.currentPage).toBe(1);
            expect(result.pagination.previousOffset).toBeNull();
        });
        test('should work with category filtering', () => {
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                category: 'task',
                limit: 10,
            });
            // Should find only task items (even numbered items)
            expect(result.totalCount).toBe(25); // 50/2 = 25 task items
            expect(result.items).toHaveLength(10);
            expect(result.items.every(item => item.category === 'task')).toBe(true);
        });
        test('should work with priority filtering', () => {
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                priorities: ['high'],
                limit: 20,
            });
            // Should find only high priority items (every 3rd item)
            expect(result.totalCount).toBe(16); // Math.floor(50/3) + some extras
            expect(result.items.every(item => item.priority === 'high')).toBe(true);
        });
        test('should work with multiple filters and pagination', () => {
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                category: 'task',
                priorities: ['normal'],
                limit: 5,
                offset: 5,
            });
            expect(result.items).toHaveLength(5);
            expect(result.items.every(item => item.category === 'task' && item.priority === 'normal')).toBe(true);
            expect(result.pagination.currentPage).toBe(2);
        });
        test('should handle empty results with pagination metadata', () => {
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'nonexistent',
                currentSessionId: sessionId,
                limit: 10,
            });
            expect(result.items).toHaveLength(0);
            expect(result.totalCount).toBe(0);
            expect(result.pagination).toMatchObject({
                currentPage: 1,
                totalPages: 0,
                totalItems: 0,
                hasNextPage: false,
                hasPreviousPage: false,
            });
        });
        test('should maintain backward compatibility with original searchAcrossSessions', () => {
            const newResult = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                sort: 'created_desc', // Use same sorting as old method
            });
            const oldResult = repositories.contexts.searchAcrossSessions('test', sessionId);
            // Old method should return all results, new method should paginate
            expect(oldResult).toHaveLength(50);
            expect(newResult.items).toHaveLength(25); // Default pagination
            expect(newResult.totalCount).toBe(50);
            // Both methods should use same sorting (priority DESC, created_at DESC)
            // Just verify the counts and that pagination works correctly
            expect(newResult.pagination).toMatchObject({
                currentPage: 1,
                totalPages: 2,
                totalItems: 50,
                itemsPerPage: 25,
                hasNextPage: true,
                hasPreviousPage: false,
            });
        });
        test('should handle large datasets without token overflow', () => {
            // Add more test data to simulate large dataset
            for (let i = 51; i <= 200; i++) {
                db.prepare('INSERT INTO context_items (id, session_id, key, value, category, priority, size) VALUES (?, ?, ?, ?, ?, ?, ?)').run((0, uuid_1.v4)(), sessionId, `large_dataset_item_${i}`, `This is a large dataset item with lots of content that could cause token overflow in the previous implementation. Item number ${i} contains substantial text content.`, 'note', 'normal', 200 // size in bytes
                );
            }
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'large',
                currentSessionId: sessionId,
                limit: 25,
            });
            // Should successfully handle large dataset with pagination
            expect(result.items).toHaveLength(25);
            expect(result.totalCount).toBe(150); // Items 51-200
            expect(result.pagination.totalPages).toBe(6); // 150/25 = 6 pages
            // Verify we can get subsequent pages
            const page2 = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'large',
                currentSessionId: sessionId,
                limit: 25,
                offset: 25,
            });
            expect(page2.items).toHaveLength(25);
            expect(page2.pagination.currentPage).toBe(2);
        });
        test('should support all search options with pagination', () => {
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                searchIn: ['key', 'value'],
                sort: 'key_asc',
                limit: 15,
                offset: 10,
                includeMetadata: true,
            });
            expect(result.items).toHaveLength(15);
            expect(result.totalCount).toBe(50);
            // Verify sorting (should be alphabetical by key)
            const keys = result.items.map(item => item.key);
            const sortedKeys = [...keys].sort();
            expect(keys).toEqual(sortedKeys);
        });
    });
    describe('Integration with cross-session functionality', () => {
        test('should work across multiple sessions with pagination', () => {
            // Create another session with data
            const session2Id = (0, uuid_1.v4)();
            db.prepare('INSERT INTO sessions (id, name, description) VALUES (?, ?, ?)').run(session2Id, 'Second Test Session', 'Second session for pagination testing');
            // Add data to second session
            for (let i = 1; i <= 30; i++) {
                db.prepare('INSERT INTO context_items (id, session_id, key, value, category, priority, is_private, size) VALUES (?, ?, ?, ?, ?, ?, ?, ?)').run((0, uuid_1.v4)(), session2Id, `session2_item_${i}`, `Session 2 test item ${i}`, 'task', 'normal', 0, // Make public so it's searchable
                50 // size in bytes
                );
            }
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                limit: 20,
            });
            // Should find items from both sessions
            expect(result.totalCount).toBe(80); // 50 from session1 + 30 from session2
            expect(result.items).toHaveLength(20);
            expect(result.pagination.totalPages).toBe(4); // 80/20 = 4
        });
        test('should respect privacy settings with pagination', () => {
            // Add private items to current session
            for (let i = 1; i <= 10; i++) {
                db.prepare('INSERT INTO context_items (id, session_id, key, value, category, priority, is_private, size) VALUES (?, ?, ?, ?, ?, ?, ?, ?)').run((0, uuid_1.v4)(), sessionId, `private_item_${i}`, `Private test item ${i}`, 'note', 'high', 1, // Private
                60 // size in bytes
                );
            }
            const result = repositories.contexts.searchAcrossSessionsEnhanced({
                query: 'test',
                currentSessionId: sessionId,
                limit: 30,
            });
            // Should include private items from current session + public items
            expect(result.totalCount).toBe(60); // 50 original + 10 private
            expect(result.items).toHaveLength(30);
        });
    });
});
