"use strict";
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 globals_1 = require("@jest/globals");
const database_1 = require("../../utils/database");
const ContextRepository_1 = require("../../repositories/ContextRepository");
const SessionRepository_1 = require("../../repositories/SessionRepository");
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const uuid_1 = require("uuid");
(0, globals_1.describe)('context_get Pagination Defaults', () => {
    let dbManager;
    let tempDbPath;
    let db;
    let contextRepo;
    let sessionRepo;
    let testSessionId;
    (0, globals_1.beforeEach)(() => {
        tempDbPath = path.join(os.tmpdir(), `test-context-get-pagination-${Date.now()}.db`);
        dbManager = new database_1.DatabaseManager({
            filename: tempDbPath,
            maxSize: 10 * 1024 * 1024,
            walMode: true,
        });
        db = dbManager.getDatabase();
        contextRepo = new ContextRepository_1.ContextRepository(dbManager);
        sessionRepo = new SessionRepository_1.SessionRepository(dbManager);
        // Create test session
        const session = sessionRepo.create({
            name: 'Test Session',
            description: 'Testing context_get pagination',
        });
        testSessionId = session.id;
    });
    (0, globals_1.afterEach)(() => {
        dbManager.close();
        try {
            fs.unlinkSync(tempDbPath);
            fs.unlinkSync(`${tempDbPath}-wal`);
            fs.unlinkSync(`${tempDbPath}-shm`);
        }
        catch (_e) {
            // Ignore
        }
    });
    (0, globals_1.describe)('Default Limit Behavior', () => {
        (0, globals_1.beforeEach)(() => {
            // Create 150 test items to test default limit
            for (let i = 0; i < 150; i++) {
                contextRepo.save(testSessionId, {
                    key: `test.item.${i.toString().padStart(3, '0')}`,
                    value: `Test value ${i}`,
                    category: i % 2 === 0 ? 'task' : 'note',
                    priority: i % 3 === 0 ? 'high' : 'normal',
                });
            }
        });
        (0, globals_1.it)('should apply default limit of 100 when limit is not provided', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                // No limit specified
            });
            (0, globals_1.expect)(result.items.length).toBe(100);
            (0, globals_1.expect)(result.totalCount).toBe(150);
        });
        (0, globals_1.it)('should apply default limit of 100 when limit is undefined', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: undefined,
            });
            (0, globals_1.expect)(result.items.length).toBe(100);
            (0, globals_1.expect)(result.totalCount).toBe(150);
        });
        (0, globals_1.it)('should respect explicit limit when provided', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: 50,
            });
            (0, globals_1.expect)(result.items.length).toBe(50);
            (0, globals_1.expect)(result.totalCount).toBe(150);
        });
        (0, globals_1.it)('should handle limit of 0 as unlimited', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: 0,
            });
            (0, globals_1.expect)(result.items.length).toBe(150); // All items
            (0, globals_1.expect)(result.totalCount).toBe(150);
        });
        (0, globals_1.it)('should treat negative limit as default (100)', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: -1,
            });
            (0, globals_1.expect)(result.items.length).toBe(100);
            (0, globals_1.expect)(result.totalCount).toBe(150);
        });
        (0, globals_1.it)('should apply default sort (created_desc) when not specified', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                // No sort specified
            });
            // Items should be sorted by created_at descending
            for (let i = 1; i < result.items.length; i++) {
                const prevDate = new Date(result.items[i - 1].created_at);
                const currDate = new Date(result.items[i].created_at);
                (0, globals_1.expect)(prevDate.getTime()).toBeGreaterThanOrEqual(currDate.getTime());
            }
        });
    });
    (0, globals_1.describe)('Pagination with Filters', () => {
        (0, globals_1.beforeEach)(() => {
            // Create items with different categories
            for (let i = 0; i < 120; i++) {
                contextRepo.save(testSessionId, {
                    key: `filtered.item.${i}`,
                    value: `Filtered value ${i}`,
                    category: i % 3 === 0 ? 'task' : i % 3 === 1 ? 'note' : 'decision',
                    priority: i % 2 === 0 ? 'high' : 'normal',
                });
            }
        });
        (0, globals_1.it)('should apply default limit with category filter', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                category: 'task',
                // No limit specified
            });
            // Should have 40 total tasks (120 / 3)
            (0, globals_1.expect)(result.totalCount).toBe(40);
            // But still limited to default of 100 (which is more than 40)
            (0, globals_1.expect)(result.items.length).toBe(40);
            (0, globals_1.expect)(result.items.every(item => item.category === 'task')).toBe(true);
        });
        (0, globals_1.it)('should apply default limit with multiple filters', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                category: 'task',
                priorities: ['high'],
                // No limit specified
            });
            // Should filter by both category and priority
            (0, globals_1.expect)(result.items.every(item => item.category === 'task' && item.priority === 'high')).toBe(true);
            // Default limit still applies
            (0, globals_1.expect)(result.items.length).toBeLessThanOrEqual(100);
        });
    });
    (0, globals_1.describe)('Offset Behavior', () => {
        (0, globals_1.beforeEach)(() => {
            // Create exactly 25 items for easier offset testing
            for (let i = 0; i < 25; i++) {
                contextRepo.save(testSessionId, {
                    key: `offset.test.${i.toString().padStart(2, '0')}`,
                    value: `Offset test value ${i}`,
                });
            }
        });
        (0, globals_1.it)('should default offset to 0 when not specified', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: 10,
                // No offset specified
            });
            (0, globals_1.expect)(result.items.length).toBe(10);
            // Should start from the beginning (most recent items due to default sort)
        });
        (0, globals_1.it)('should handle offset with default limit', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                offset: 10,
                // No limit specified - should default to 100
            });
            (0, globals_1.expect)(result.items.length).toBe(15); // 25 total - 10 offset = 15 remaining
        });
        (0, globals_1.it)('should handle negative offset as 0', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                offset: -10,
                limit: 5,
            });
            (0, globals_1.expect)(result.items.length).toBe(5);
            // Should behave as if offset was 0
        });
    });
    (0, globals_1.describe)('Edge Cases', () => {
        (0, globals_1.it)('should handle empty result set gracefully', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                category: 'non-existent-category',
            });
            (0, globals_1.expect)(result.items.length).toBe(0);
            (0, globals_1.expect)(result.totalCount).toBe(0);
        });
        (0, globals_1.it)('should handle offset beyond available items', () => {
            // Create only 5 items
            for (let i = 0; i < 5; i++) {
                contextRepo.save(testSessionId, {
                    key: `limited.${i}`,
                    value: `Limited value ${i}`,
                });
            }
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                offset: 100, // Far beyond available items
                // No limit specified
            });
            (0, globals_1.expect)(result.items.length).toBe(0);
            (0, globals_1.expect)(result.totalCount).toBe(5);
        });
        (0, globals_1.it)('should handle very large datasets efficiently', () => {
            // Create 1000 items
            const stmt = db.prepare(`
        INSERT INTO context_items (id, session_id, key, value, created_at)
        VALUES (?, ?, ?, ?, ?)
      `);
            const _startCreate = Date.now();
            for (let i = 0; i < 1000; i++) {
                stmt.run((0, uuid_1.v4)(), testSessionId, `large.dataset.${i.toString().padStart(4, '0')}`, `Large dataset value ${i}`, new Date(Date.now() - i * 1000).toISOString());
            }
            const _endCreate = Date.now();
            const startQuery = Date.now();
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                // No limit specified - should default to 100
            });
            const endQuery = Date.now();
            (0, globals_1.expect)(result.items.length).toBe(100); // Default limit
            (0, globals_1.expect)(result.totalCount).toBe(1000);
            // Query should be fast even with 1000 items
            const queryTime = endQuery - startQuery;
            (0, globals_1.expect)(queryTime).toBeLessThan(100); // Should complete in < 100ms
            // Performance metrics (using underscored vars to avoid lint errors):
            // Created 1000 items in ${_endCreate - _startCreate}ms
            // Queried with default limit in ${queryTime}ms
        });
    });
    (0, globals_1.describe)('Repository Type Handling', () => {
        (0, globals_1.it)('should handle string numbers that can be converted', () => {
            // The repository's type checking will treat non-numbers as undefined
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: '50', // String that looks like a number
            });
            // Repository treats non-numbers as undefined, so it applies default
            (0, globals_1.expect)(result.items.length).toBeLessThanOrEqual(100);
        });
        (0, globals_1.it)('should treat non-numeric types as undefined and apply defaults', () => {
            // Create some test items
            for (let i = 0; i < 10; i++) {
                contextRepo.save(testSessionId, {
                    key: `type.test.${i}`,
                    value: `Type test value ${i}`,
                });
            }
            // Repository checks typeof limit === 'number'
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: 'not-a-number',
            });
            // Should apply default limit of 100
            (0, globals_1.expect)(result.items.length).toBe(10); // We only have 10 items
            (0, globals_1.expect)(result.totalCount).toBe(10);
        });
    });
});
