"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 os = __importStar(require("os"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const uuid_1 = require("uuid");
(0, globals_1.describe)('Enhanced Context Get Handler Integration Tests', () => {
    let dbManager;
    let tempDbPath;
    let db;
    let contextRepo;
    let testSessionId;
    let secondSessionId;
    (0, globals_1.beforeEach)(() => {
        tempDbPath = path.join(os.tmpdir(), `test-enhanced-context-get-${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);
        // Create test sessions
        testSessionId = (0, uuid_1.v4)();
        secondSessionId = (0, uuid_1.v4)();
        db.prepare('INSERT INTO sessions (id, name) VALUES (?, ?)').run(testSessionId, 'Test Session');
        db.prepare('INSERT INTO sessions (id, name) VALUES (?, ?)').run(secondSessionId, 'Second Session');
    });
    (0, globals_1.afterEach)(() => {
        dbManager.close();
        try {
            fs.unlinkSync(tempDbPath);
            fs.unlinkSync(`${tempDbPath}-wal`);
            fs.unlinkSync(`${tempDbPath}-shm`);
        }
        catch (_e) {
            // Ignore
        }
    });
    function createTestData() {
        const now = new Date();
        const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
        const oneDayAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000);
        const twoDaysAgo = new Date(now.getTime() - 2 * 24 * 60 * 60 * 1000);
        const oneWeekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
        // Create a timestamp that's definitely yesterday
        const yesterday = new Date();
        yesterday.setDate(yesterday.getDate() - 1);
        yesterday.setHours(12, 0, 0, 0); // Noon yesterday
        const items = [
            {
                id: (0, uuid_1.v4)(),
                session_id: testSessionId,
                key: 'config.database.url',
                value: 'postgresql://localhost:5432/myapp',
                category: 'config',
                priority: 'high',
                channel: 'main',
                created_at: now.toISOString(),
                updated_at: now.toISOString(),
                metadata: JSON.stringify({ environment: 'production' }),
                size: 35,
            },
            // Add an item from yesterday
            {
                id: (0, uuid_1.v4)(),
                session_id: testSessionId,
                key: 'config.yesterday.item',
                value: 'Created yesterday',
                category: 'config',
                priority: 'normal',
                channel: 'main',
                created_at: yesterday.toISOString(),
                updated_at: yesterday.toISOString(),
                size: 17,
            },
            {
                id: (0, uuid_1.v4)(),
                session_id: testSessionId,
                key: 'config.cache.ttl',
                value: '3600',
                category: 'config',
                priority: 'normal',
                channel: 'main',
                created_at: oneHourAgo.toISOString(),
                updated_at: oneHourAgo.toISOString(),
                metadata: JSON.stringify({ unit: 'seconds' }),
                size: 4,
            },
            {
                id: (0, uuid_1.v4)(),
                session_id: testSessionId,
                key: 'task.deploy.status',
                value: 'completed',
                category: 'task',
                priority: 'high',
                channel: 'deployment',
                created_at: oneDayAgo.toISOString(),
                updated_at: oneHourAgo.toISOString(),
                size: 9,
            },
            {
                id: (0, uuid_1.v4)(),
                session_id: testSessionId,
                key: 'task.backup.status',
                value: 'pending',
                category: 'task',
                priority: 'low',
                channel: 'maintenance',
                created_at: twoDaysAgo.toISOString(),
                updated_at: twoDaysAgo.toISOString(),
                size: 7,
            },
            {
                id: (0, uuid_1.v4)(),
                session_id: testSessionId,
                key: 'note.architecture',
                value: 'The system uses a microservices architecture with Docker containers',
                category: 'note',
                priority: 'normal',
                channel: 'documentation',
                created_at: oneWeekAgo.toISOString(),
                updated_at: oneWeekAgo.toISOString(),
                size: 67,
            },
            // Private item
            {
                id: (0, uuid_1.v4)(),
                session_id: testSessionId,
                key: 'secret.api.key',
                value: 'sk-1234567890abcdef',
                category: 'config',
                priority: 'high',
                channel: 'secure',
                created_at: now.toISOString(),
                updated_at: now.toISOString(),
                is_private: 1,
                size: 18,
            },
            // Item from another session (public)
            {
                id: (0, uuid_1.v4)(),
                session_id: secondSessionId,
                key: 'shared.resource',
                value: 'This is a shared resource',
                category: 'shared',
                priority: 'normal',
                channel: 'public',
                created_at: oneDayAgo.toISOString(),
                is_private: 0,
                size: 25,
            },
        ];
        // Insert test data
        const stmt = db.prepare(`
      INSERT INTO context_items (
        id, session_id, key, value, category, priority, channel, 
        created_at, updated_at, metadata, size, is_private
      ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);
        items.forEach(item => {
            stmt.run(item.id, item.session_id, item.key, item.value, item.category || null, item.priority || 'normal', item.channel || 'general', item.created_at || new Date().toISOString(), item.updated_at || item.created_at || new Date().toISOString(), item.metadata || null, item.size || Buffer.byteLength(item.value, 'utf8'), item.is_private || 0);
        });
    }
    (0, globals_1.describe)('Backward Compatibility Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should return single value when requesting by key (backward compatible)', () => {
            const result = contextRepo.getByKey(testSessionId, 'config.database.url');
            (0, globals_1.expect)(result).toBeTruthy();
            (0, globals_1.expect)(result.value).toBe('postgresql://localhost:5432/myapp');
            // Handler should return just the value for single key requests
            // This simulates the handler behavior
            const handlerResponse = {
                content: [{ type: 'text', text: result.value }],
            };
            (0, globals_1.expect)(handlerResponse.content[0].text).toBe('postgresql://localhost:5432/myapp');
        });
        (0, globals_1.it)('should return text format for multiple items by default', () => {
            const items = contextRepo.getByCategory(testSessionId, 'config');
            (0, globals_1.expect)(items.length).toBeGreaterThan(1);
            // Simulate handler formatting for multiple items
            const formattedItems = items
                .filter(item => !item.is_private || item.session_id === testSessionId)
                .map(r => `• [${r.priority}] ${r.key}: ${r.value.substring(0, 100)}${r.value.length > 100 ? '...' : ''}`)
                .join('\n');
            const handlerResponse = {
                content: [
                    {
                        type: 'text',
                        text: `Found ${items.length} context items:\n\n${formattedItems}`,
                    },
                ],
            };
            (0, globals_1.expect)(handlerResponse.content[0].text).toContain('Found');
            (0, globals_1.expect)(handlerResponse.content[0].text).toContain('config.database.url');
            (0, globals_1.expect)(handlerResponse.content[0].text).toContain('[high]');
        });
        (0, globals_1.it)('should handle category parameter (existing functionality)', () => {
            const items = contextRepo.getByCategory(testSessionId, 'task');
            (0, globals_1.expect)(items.length).toBe(2);
            (0, globals_1.expect)(items.every(item => item.category === 'task')).toBe(true);
        });
        (0, globals_1.it)('should respect session isolation by default', () => {
            const items = contextRepo.getBySessionId(testSessionId);
            (0, globals_1.expect)(items.every(item => item.session_id === testSessionId)).toBe(true);
            (0, globals_1.expect)(items.some(item => item.key === 'shared.resource')).toBe(false);
        });
    });
    (0, globals_1.describe)('Metadata Inclusion Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should include metadata when includeMetadata is true', () => {
            const options = {
                sessionId: testSessionId,
                key: 'config.database.url',
                includeMetadata: true,
            };
            const result = contextRepo.queryEnhanced(options);
            (0, globals_1.expect)(result.items.length).toBe(1);
            const item = result.items[0];
            // Verify all metadata fields are present
            (0, globals_1.expect)(item).toHaveProperty('size');
            (0, globals_1.expect)(item).toHaveProperty('created_at');
            (0, globals_1.expect)(item).toHaveProperty('updated_at');
            (0, globals_1.expect)(item).toHaveProperty('metadata');
            (0, globals_1.expect)(item.size).toBe(35);
            // Verify metadata can be parsed
            if (item.metadata) {
                const parsed = JSON.parse(item.metadata);
                (0, globals_1.expect)(parsed).toHaveProperty('environment', 'production');
            }
        });
        (0, globals_1.it)('should return metadata structure for multiple items', () => {
            const options = {
                sessionId: testSessionId,
                category: 'config',
                includeMetadata: true,
            };
            const result = contextRepo.queryEnhanced(options);
            // Should return object with items array and totalCount
            (0, globals_1.expect)(result).toHaveProperty('items');
            (0, globals_1.expect)(result).toHaveProperty('totalCount');
            (0, globals_1.expect)(result.totalCount).toBeGreaterThanOrEqual(result.items.length);
            result.items.forEach(item => {
                (0, globals_1.expect)(item).toHaveProperty('size');
                (0, globals_1.expect)(item).toHaveProperty('created_at');
                (0, globals_1.expect)(item).toHaveProperty('updated_at');
            });
        });
    });
    (0, globals_1.describe)('Sorting Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should sort by created_at descending (default)', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                sort: 'created_desc',
            });
            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.it)('should sort by created_at ascending', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                sort: 'created_asc',
            });
            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()).toBeLessThanOrEqual(currDate.getTime());
            }
        });
        (0, globals_1.it)('should sort by updated_at descending', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                sort: 'updated_desc',
            });
            // Verify items are sorted by updated_at in descending order
            for (let i = 1; i < result.items.length; i++) {
                const prevDate = new Date(result.items[i - 1].updated_at);
                const currDate = new Date(result.items[i].updated_at);
                (0, globals_1.expect)(prevDate.getTime()).toBeGreaterThanOrEqual(currDate.getTime());
            }
            // The most recently updated items should be first
            // config.database.url and secret.api.key both have updated_at = now
            (0, globals_1.expect)(['config.database.url', 'secret.api.key']).toContain(result.items[0].key);
        });
        (0, globals_1.it)('should sort by key ascending', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                sort: 'key_asc',
            });
            for (let i = 1; i < result.items.length; i++) {
                (0, globals_1.expect)(result.items[i - 1].key.localeCompare(result.items[i].key)).toBeLessThanOrEqual(0);
            }
        });
        (0, globals_1.it)('should sort by key descending', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                sort: 'key_desc',
            });
            for (let i = 1; i < result.items.length; i++) {
                (0, globals_1.expect)(result.items[i - 1].key.localeCompare(result.items[i].key)).toBeGreaterThanOrEqual(0);
            }
        });
        (0, globals_1.it)('should handle priority-based sorting when no sort specified', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                category: 'task',
            });
            // High priority items should come first
            (0, globals_1.expect)(result.items[0].priority).toBe('high');
        });
    });
    (0, globals_1.describe)('Pagination Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
            // Add more items for pagination testing
            for (let i = 0; i < 10; i++) {
                db.prepare(`
          INSERT INTO context_items (id, session_id, key, value, category, priority)
          VALUES (?, ?, ?, ?, ?, ?)
        `).run((0, uuid_1.v4)(), testSessionId, `test.item.${i}`, `Test value ${i}`, 'test', 'normal');
            }
        });
        (0, globals_1.it)('should limit results correctly', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: 5,
            });
            (0, globals_1.expect)(result.items.length).toBe(5);
            (0, globals_1.expect)(result.totalCount).toBeGreaterThan(5);
        });
        (0, globals_1.it)('should handle offset correctly', () => {
            const resultPage1 = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: 5,
                offset: 0,
            });
            const resultPage2 = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: 5,
                offset: 5,
            });
            // Ensure no overlap between pages
            const page1Keys = new Set(resultPage1.items.map(item => item.key));
            const page2Keys = new Set(resultPage2.items.map(item => item.key));
            page2Keys.forEach(key => {
                (0, globals_1.expect)(page1Keys.has(key)).toBe(false);
            });
        });
        (0, globals_1.it)('should calculate correct pagination metadata', () => {
            const pageSize = 3;
            const page = 2;
            const offset = (page - 1) * pageSize;
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: pageSize,
                offset: offset,
            });
            // Handler would calculate these values
            const totalPages = Math.ceil(result.totalCount / pageSize);
            const hasNextPage = page < totalPages;
            const hasPreviousPage = page > 1;
            (0, globals_1.expect)(result.items.length).toBeLessThanOrEqual(pageSize);
            (0, globals_1.expect)(hasNextPage).toBe(true);
            (0, globals_1.expect)(hasPreviousPage).toBe(true);
        });
    });
    (0, globals_1.describe)('Time Filtering Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should filter by createdAfter with ISO date', () => {
            const twoDaysAgo = new Date();
            twoDaysAgo.setDate(twoDaysAgo.getDate() - 2);
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                createdAfter: twoDaysAgo.toISOString(),
            });
            result.items.forEach(item => {
                (0, globals_1.expect)(new Date(item.created_at).getTime()).toBeGreaterThan(twoDaysAgo.getTime());
            });
            // Should include recent items but not older ones
            (0, globals_1.expect)(result.items.some(item => item.key === 'config.database.url')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'note.architecture')).toBe(false);
        });
        (0, globals_1.it)('should filter by createdBefore with ISO date', () => {
            const oneDayAgo = new Date();
            oneDayAgo.setDate(oneDayAgo.getDate() - 1);
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                createdBefore: oneDayAgo.toISOString(),
            });
            result.items.forEach(item => {
                (0, globals_1.expect)(new Date(item.created_at).getTime()).toBeLessThan(oneDayAgo.getTime());
            });
            // Should include older items but not recent ones
            (0, globals_1.expect)(result.items.some(item => item.key === 'note.architecture')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'config.database.url')).toBe(false);
        });
        (0, globals_1.it)('should handle relative time for createdAfter', () => {
            // Test "2 hours ago"
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                createdAfter: '2 hours ago',
            });
            // Should include items created within last 2 hours
            (0, globals_1.expect)(result.items.some(item => item.key === 'config.database.url')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'config.cache.ttl')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'task.deploy.status')).toBe(false);
        });
        (0, globals_1.it)('should handle "today" relative time', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                createdAfter: 'today',
            });
            const today = new Date();
            today.setHours(0, 0, 0, 0);
            result.items.forEach(item => {
                const itemDate = new Date(item.created_at);
                (0, globals_1.expect)(itemDate.getTime()).toBeGreaterThanOrEqual(today.getTime());
            });
        });
        (0, globals_1.it)('should handle "yesterday" relative time', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                createdAfter: 'yesterday',
                createdBefore: 'today',
            });
            const today = new Date();
            today.setHours(0, 0, 0, 0);
            const yesterday = new Date(today);
            yesterday.setDate(yesterday.getDate() - 1);
            result.items.forEach(item => {
                const itemDate = new Date(item.created_at);
                (0, globals_1.expect)(itemDate.getTime()).toBeGreaterThanOrEqual(yesterday.getTime());
                (0, globals_1.expect)(itemDate.getTime()).toBeLessThan(today.getTime());
            });
        });
        (0, globals_1.it)('should handle combined date range', () => {
            // Use a slightly larger range to account for timing
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                createdAfter: '8 days ago',
                createdBefore: '1 hour ago',
            });
            // Should include items from the past week but not the most recent items
            (0, globals_1.expect)(result.items.some(item => item.key === 'note.architecture')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'task.backup.status')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'task.deploy.status')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'config.database.url')).toBe(false); // created "now"
            (0, globals_1.expect)(result.items.some(item => item.key === 'secret.api.key')).toBe(false); // created "now"
        });
    });
    (0, globals_1.describe)('Priority Filtering Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should filter by single priority', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                priorities: ['high'],
            });
            (0, globals_1.expect)(result.items.every(item => item.priority === 'high')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'config.database.url')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'task.deploy.status')).toBe(true);
        });
        (0, globals_1.it)('should filter by multiple priorities', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                priorities: ['high', 'low'],
            });
            (0, globals_1.expect)(result.items.every(item => item.priority === 'high' || item.priority === 'low')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.priority === 'normal')).toBe(false);
        });
        (0, globals_1.it)('should handle empty priorities array', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                priorities: [],
            });
            // Should return all items when no priority filter
            (0, globals_1.expect)(result.items.length).toBeGreaterThan(0);
        });
    });
    (0, globals_1.describe)('Pattern Matching Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should match keys with simple pattern', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                keyPattern: 'config.*',
            });
            (0, globals_1.expect)(result.items.every(item => item.key.startsWith('config.'))).toBe(true);
            (0, globals_1.expect)(result.items.length).toBe(3); // config.database.url, config.cache.ttl, and config.yesterday.item
        });
        (0, globals_1.it)('should match keys ending with pattern', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                keyPattern: '*.status',
            });
            (0, globals_1.expect)(result.items.every(item => item.key.endsWith('.status'))).toBe(true);
            (0, globals_1.expect)(result.items.length).toBe(2); // task.deploy.status and task.backup.status
        });
        (0, globals_1.it)('should match keys with middle wildcard', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                keyPattern: 'task.*.status',
            });
            (0, globals_1.expect)(result.items.every(item => item.key.startsWith('task.') && item.key.endsWith('.status'))).toBe(true);
        });
        (0, globals_1.it)('should handle regex special characters in pattern', () => {
            // Add item with special characters
            db.prepare(`
        INSERT INTO context_items (id, session_id, key, value)
        VALUES (?, ?, ?, ?)
      `).run((0, uuid_1.v4)(), testSessionId, 'config.db[prod].host', 'localhost');
            // Pattern should handle [ ] characters
            // In GLOB, we need to match literal brackets and any content between them
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                keyPattern: 'config.db*prod*.host',
            });
            (0, globals_1.expect)(result.items.length).toBe(1);
            (0, globals_1.expect)(result.items[0].key).toBe('config.db[prod].host');
        });
    });
    (0, globals_1.describe)('Channel Filtering Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should filter by single channel', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                channel: 'main',
            });
            (0, globals_1.expect)(result.items.every(item => item.channel === 'main')).toBe(true);
            (0, globals_1.expect)(result.items.length).toBe(3); // includes config.yesterday.item
        });
        (0, globals_1.it)('should filter by multiple channels', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                channels: ['main', 'deployment'],
            });
            (0, globals_1.expect)(result.items.every(item => item.channel === 'main' || item.channel === 'deployment')).toBe(true);
            (0, globals_1.expect)(result.items.length).toBe(4); // 3 from main + 1 from deployment
        });
        (0, globals_1.it)('should handle both channel and channels parameters', () => {
            // When both are provided, channels array should take precedence
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                channel: 'main',
                channels: ['deployment', 'maintenance'],
            });
            // Should only return items from channels array
            (0, globals_1.expect)(result.items.every(item => item.channel === 'deployment' || item.channel === 'maintenance')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.channel === 'main')).toBe(false);
        });
    });
    (0, globals_1.describe)('Combined Parameter Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should handle multiple filters together', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                category: 'task',
                priorities: ['high', 'normal'],
                createdAfter: '3 days ago',
                sort: 'created_desc',
                limit: 10,
            });
            (0, globals_1.expect)(result.items.every(item => item.category === 'task' && (item.priority === 'high' || item.priority === 'normal'))).toBe(true);
            // Should include task.deploy.status but not task.backup.status (low priority)
            (0, globals_1.expect)(result.items.some(item => item.key === 'task.deploy.status')).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'task.backup.status')).toBe(false);
        });
        (0, globals_1.it)('should handle pattern with other filters', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                keyPattern: '*.status',
                priorities: ['high'],
                includeMetadata: true,
            });
            (0, globals_1.expect)(result.items.length).toBe(1);
            (0, globals_1.expect)(result.items[0].key).toBe('task.deploy.status');
            (0, globals_1.expect)(result.items[0]).toHaveProperty('size');
            (0, globals_1.expect)(result.items[0]).toHaveProperty('created_at');
        });
        (0, globals_1.it)('should handle time range with channels and pagination', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                channels: ['main', 'deployment', 'maintenance'],
                createdAfter: '7 days ago',
                createdBefore: 'today',
                sort: 'key_asc',
                limit: 2,
                offset: 0,
            });
            (0, globals_1.expect)(result.items.length).toBeLessThanOrEqual(2);
            (0, globals_1.expect)(result.totalCount).toBeGreaterThanOrEqual(result.items.length);
            // Verify sorting
            if (result.items.length > 1) {
                (0, globals_1.expect)(result.items[0].key.localeCompare(result.items[1].key)).toBeLessThanOrEqual(0);
            }
        });
    });
    (0, globals_1.describe)('Privacy and Access Control Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should include own private items', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                category: 'config',
            });
            // Should include private secret.api.key since it's from the same session
            (0, globals_1.expect)(result.items.some(item => item.key === 'secret.api.key')).toBe(true);
        });
        (0, globals_1.it)('should include public items from other sessions', () => {
            const result = contextRepo.getAccessibleItems(testSessionId);
            // Should include shared.resource from another session
            (0, globals_1.expect)(result.some(item => item.key === 'shared.resource')).toBe(true);
        });
        (0, globals_1.it)('should not include private items from other sessions', () => {
            // Add private item in second session
            db.prepare(`
        INSERT INTO context_items (id, session_id, key, value, is_private)
        VALUES (?, ?, ?, ?, ?)
      `).run((0, uuid_1.v4)(), secondSessionId, 'other.private', 'Private data', 1);
            const result = contextRepo.getAccessibleItems(testSessionId);
            // Should not include other session's private item
            (0, globals_1.expect)(result.some(item => item.key === 'other.private')).toBe(false);
        });
    });
    (0, globals_1.describe)('Error Handling Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should handle non-existent session gracefully', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: 'non-existent-session',
            });
            // When session doesn't exist, it returns public items from other sessions
            (0, globals_1.expect)(result.items.length).toBeGreaterThan(0);
            (0, globals_1.expect)(result.items.every(item => item.is_private === 0)).toBe(true);
            (0, globals_1.expect)(result.items.some(item => item.key === 'shared.resource')).toBe(true);
        });
        (0, globals_1.it)('should handle invalid sort parameter', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                sort: 'invalid_sort',
            });
            // Should fall back to default sort
            (0, globals_1.expect)(result.items.length).toBeGreaterThan(0);
        });
        (0, globals_1.it)('should handle invalid date formats', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                createdAfter: 'invalid date',
            });
            // Should treat as literal string and likely return no results
            (0, globals_1.expect)(result.items).toEqual([]);
        });
        (0, globals_1.it)('should handle negative offset', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: 5,
                offset: -1,
            });
            // Should treat negative offset as 0
            (0, globals_1.expect)(result.items.length).toBeGreaterThan(0);
        });
        (0, globals_1.it)('should handle very large limit', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                limit: 999999,
            });
            // Should return all available items
            (0, globals_1.expect)(result.items.length).toBe(result.totalCount);
        });
        (0, globals_1.it)('should handle SQL injection attempts in keyPattern', () => {
            const maliciousPattern = "'; DROP TABLE context_items; --";
            // Should not throw and should not damage database
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                keyPattern: maliciousPattern,
            });
            // Verify table still exists
            const tableExists = db
                .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='context_items'")
                .get();
            (0, globals_1.expect)(tableExists).toBeTruthy();
            (0, globals_1.expect)(result.items).toEqual([]);
        });
    });
    (0, globals_1.describe)('Handler Response Format Tests', () => {
        (0, globals_1.beforeEach)(() => {
            createTestData();
        });
        (0, globals_1.it)('should format single item response correctly', () => {
            const item = contextRepo.getByKey(testSessionId, 'config.database.url');
            // Handler returns just the value for single key request
            const handlerResponse = {
                content: [
                    {
                        type: 'text',
                        text: item.value,
                    },
                ],
            };
            (0, globals_1.expect)(handlerResponse.content[0].text).toBe('postgresql://localhost:5432/myapp');
        });
        (0, globals_1.it)('should format multiple items without metadata', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                category: 'config',
            });
            // Handler formats as text list
            const formattedItems = result.items
                .map(r => `• [${r.priority}] ${r.key}: ${r.value.substring(0, 100)}${r.value.length > 100 ? '...' : ''}`)
                .join('\n');
            const handlerResponse = {
                content: [
                    {
                        type: 'text',
                        text: `Found ${result.items.length} context items:\n\n${formattedItems}`,
                    },
                ],
            };
            (0, globals_1.expect)(handlerResponse.content[0].text).toContain('Found');
            (0, globals_1.expect)(handlerResponse.content[0].text).toContain('• [');
            (0, globals_1.expect)(handlerResponse.content[0].text.split('\n').length).toBeGreaterThan(2);
        });
        (0, globals_1.it)('should format response with metadata as JSON', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                category: 'config',
                includeMetadata: true,
                limit: 10,
                offset: 0,
            });
            // Handler returns structured data with metadata
            const handlerResponse = {
                content: [
                    {
                        type: 'text',
                        text: JSON.stringify({
                            items: result.items.map(item => ({
                                key: item.key,
                                value: item.value,
                                category: item.category,
                                priority: item.priority,
                                channel: item.channel,
                                metadata: item.metadata ? JSON.parse(item.metadata) : null,
                                size: item.size,
                                created_at: item.created_at,
                                updated_at: item.updated_at,
                            })),
                            pagination: {
                                totalCount: result.totalCount,
                                page: 1,
                                pageSize: 10,
                                totalPages: Math.ceil(result.totalCount / 10),
                                hasNextPage: result.totalCount > 10,
                                hasPreviousPage: false,
                            },
                        }, null, 2),
                    },
                ],
            };
            const parsed = JSON.parse(handlerResponse.content[0].text);
            (0, globals_1.expect)(parsed).toHaveProperty('items');
            (0, globals_1.expect)(parsed).toHaveProperty('pagination');
            (0, globals_1.expect)(parsed.pagination).toHaveProperty('totalCount');
            (0, globals_1.expect)(parsed.items[0]).toHaveProperty('size');
            (0, globals_1.expect)(parsed.items[0]).toHaveProperty('created_at');
        });
        (0, globals_1.it)('should handle empty results gracefully', () => {
            const _result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                key: 'non-existent-key',
            });
            const handlerResponse = {
                content: [
                    {
                        type: 'text',
                        text: 'No matching context found',
                    },
                ],
            };
            (0, globals_1.expect)(handlerResponse.content[0].text).toBe('No matching context found');
        });
    });
    (0, globals_1.describe)('Performance and Edge Cases', () => {
        (0, globals_1.it)('should handle large number of items efficiently', () => {
            // Add 100 items
            for (let i = 0; i < 100; i++) {
                db.prepare(`
          INSERT INTO context_items (id, session_id, key, value, priority)
          VALUES (?, ?, ?, ?, ?)
        `).run((0, uuid_1.v4)(), testSessionId, `perf.test.${i.toString().padStart(3, '0')}`, `Performance test value ${i}`, i % 3 === 0 ? 'high' : 'normal');
            }
            const startTime = Date.now();
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                keyPattern: 'perf.test.*',
                priorities: ['high'],
                sort: 'key_desc',
                limit: 20,
            });
            const endTime = Date.now();
            (0, globals_1.expect)(result.items.length).toBe(20);
            (0, globals_1.expect)(result.totalCount).toBeGreaterThan(20);
            (0, globals_1.expect)(endTime - startTime).toBeLessThan(100); // Should complete within 100ms
        });
        (0, globals_1.it)('should handle unicode and special characters in values', () => {
            const unicodeKey = 'unicode.test';
            const unicodeValue = '🚀 Unicode test with émojis and spëcial çharacters';
            db.prepare(`
        INSERT INTO context_items (id, session_id, key, value)
        VALUES (?, ?, ?, ?)
      `).run((0, uuid_1.v4)(), testSessionId, unicodeKey, unicodeValue);
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                key: unicodeKey,
            });
            (0, globals_1.expect)(result.items.length).toBe(1);
            (0, globals_1.expect)(result.items[0].value).toBe(unicodeValue);
        });
        (0, globals_1.it)('should handle very long values', () => {
            const longValue = 'A'.repeat(10000);
            db.prepare(`
        INSERT INTO context_items (id, session_id, key, value, size)
        VALUES (?, ?, ?, ?, ?)
      `).run((0, uuid_1.v4)(), testSessionId, 'long.value', longValue, Buffer.byteLength(longValue, 'utf8'));
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                key: 'long.value',
                includeMetadata: true,
            });
            (0, globals_1.expect)(result.items.length).toBe(1);
            (0, globals_1.expect)(result.items[0].value.length).toBe(10000);
            (0, globals_1.expect)(result.items[0].size).toBe(10000);
        });
        (0, globals_1.it)('should handle all parameters at once', () => {
            const result = contextRepo.queryEnhanced({
                sessionId: testSessionId,
                key: undefined,
                category: 'config',
                channel: undefined,
                channels: ['main', 'secure'],
                sort: 'created_desc',
                limit: 5,
                offset: 0,
                createdAfter: '7 days ago',
                createdBefore: 'now',
                keyPattern: 'config.*',
                priorities: ['high', 'normal'],
                includeMetadata: true,
            });
            // Should apply all filters correctly
            (0, globals_1.expect)(result.items.every(item => item.category === 'config' &&
                item.key.startsWith('config.') &&
                (item.channel === 'main' || item.channel === 'secure') &&
                (item.priority === 'high' || item.priority === 'normal'))).toBe(true);
            (0, globals_1.expect)(result).toHaveProperty('totalCount');
            (0, globals_1.expect)(result.items.length).toBeLessThanOrEqual(5);
        });
    });
});
