"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 database_1 = require("../../utils/database");
const knowledge_graph_1 = require("../../utils/knowledge-graph");
const vector_store_1 = require("../../utils/vector-store");
const agents_1 = require("../../utils/agents");
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const uuid_1 = require("uuid");
describe('Multi-Agent System Integration Tests', () => {
    let dbManager;
    let tempDbPath;
    let db;
    let testSessionId;
    let knowledgeGraph;
    let vectorStore;
    let agentCoordinator;
    beforeEach(() => {
        tempDbPath = path.join(os.tmpdir(), `test-multiagent-${Date.now()}.db`);
        dbManager = new database_1.DatabaseManager({
            filename: tempDbPath,
            maxSize: 10 * 1024 * 1024,
            walMode: true,
        });
        db = dbManager.getDatabase();
        // Initialize components
        knowledgeGraph = new knowledge_graph_1.KnowledgeGraphManager(db);
        vectorStore = new vector_store_1.VectorStore(db);
        agentCoordinator = new agents_1.AgentCoordinator();
        // Register agents
        const analyzerAgent = new agents_1.AnalyzerAgent(db, knowledgeGraph, vectorStore);
        const synthesizerAgent = new agents_1.SynthesizerAgent(db, vectorStore);
        agentCoordinator.registerAgent(analyzerAgent);
        agentCoordinator.registerAgent(synthesizerAgent);
        // Create test session
        testSessionId = (0, uuid_1.v4)();
        db.prepare('INSERT INTO sessions (id, name, description) VALUES (?, ?, ?)').run(testSessionId, 'Multi-Agent Test', 'Testing multi-agent system');
    });
    afterEach(() => {
        dbManager.close();
        try {
            fs.unlinkSync(tempDbPath);
            fs.unlinkSync(`${tempDbPath}-wal`);
            fs.unlinkSync(`${tempDbPath}-shm`);
        }
        catch (_e) {
            // Ignore
        }
    });
    describe('Pattern Analysis', () => {
        beforeEach(() => {
            // Create diverse test data
            const items = [
                // Tasks
                {
                    key: 'implement_auth',
                    value: 'Implement OAuth2 authentication flow',
                    category: 'task',
                    priority: 'high',
                },
                {
                    key: 'add_tests',
                    value: 'Add unit tests for auth module',
                    category: 'task',
                    priority: 'high',
                },
                {
                    key: 'update_docs',
                    value: 'Update API documentation',
                    category: 'task',
                    priority: 'normal',
                },
                {
                    key: 'fix_bug_123',
                    value: 'Fix login timeout issue',
                    category: 'task',
                    priority: 'high',
                },
                {
                    key: 'refactor_db',
                    value: 'Refactor database connection pool',
                    category: 'task',
                    priority: 'low',
                },
                // Decisions
                {
                    key: 'use_jwt',
                    value: 'Use JWT tokens with 24h expiry',
                    category: 'decision',
                    priority: 'high',
                },
                {
                    key: 'db_choice',
                    value: 'Use PostgreSQL for main database',
                    category: 'decision',
                    priority: 'high',
                },
                {
                    key: 'cache_strategy',
                    value: 'Implement Redis caching for sessions',
                    category: 'decision',
                    priority: 'normal',
                },
                // Progress
                {
                    key: 'login_complete',
                    value: 'Completed login form UI',
                    category: 'progress',
                    priority: 'normal',
                },
                {
                    key: 'api_designed',
                    value: 'Designed REST API endpoints',
                    category: 'progress',
                    priority: 'normal',
                },
                {
                    key: 'tests_passing',
                    value: 'All auth tests passing',
                    category: 'progress',
                    priority: 'normal',
                },
                // Notes
                {
                    key: 'security_note',
                    value: 'Remember to add rate limiting',
                    category: 'note',
                    priority: 'high',
                },
                {
                    key: 'performance_tip',
                    value: 'Consider connection pooling',
                    category: 'note',
                    priority: 'normal',
                },
            ];
            for (const item of items) {
                db.prepare('INSERT INTO context_items (id, session_id, key, value, category, priority, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)').run((0, uuid_1.v4)(), testSessionId, item.key, item.value, item.category, item.priority, new Date().toISOString());
            }
        });
        it('should analyze patterns and provide insights', async () => {
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'analyze',
                input: {
                    analysisType: 'patterns',
                    sessionId: testSessionId,
                },
            };
            const results = await agentCoordinator.delegate(task);
            expect(results.length).toBe(1);
            expect(results[0].agentType).toBe('analyzer');
            expect(results[0].confidence).toBeGreaterThan(0.7);
            const output = results[0].output;
            expect(output.patterns).toBeDefined();
            expect(output.patterns.categoryDistribution.task).toBe(5);
            expect(output.patterns.categoryDistribution.decision).toBe(3);
            expect(output.patterns.priorityDistribution.high).toBe(6);
            expect(output.insights).toBeInstanceOf(Array);
            expect(output.insights.length).toBeGreaterThan(0);
        });
        it('should filter analysis by categories', async () => {
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'analyze',
                input: {
                    analysisType: 'patterns',
                    sessionId: testSessionId,
                    categories: ['task', 'decision'],
                },
            };
            const results = await agentCoordinator.delegate(task);
            const output = results[0].output;
            expect(output.itemCount).toBe(8); // 5 tasks + 3 decisions
            expect(output.patterns.categoryDistribution.progress).toBeUndefined();
            expect(output.patterns.categoryDistribution.note).toBeUndefined();
        });
        it('should analyze temporal patterns', async () => {
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'analyze',
                input: {
                    analysisType: 'patterns',
                    sessionId: testSessionId,
                    timeframe: '-7 days',
                },
            };
            const results = await agentCoordinator.delegate(task);
            const output = results[0].output;
            expect(output.patterns.temporalPatterns).toBeDefined();
            expect(output.patterns.temporalPatterns.hourly).toBeDefined();
            expect(output.patterns.temporalPatterns.daily).toBeDefined();
        });
    });
    describe('Relationship Analysis', () => {
        beforeEach(() => {
            // Create entities and relationships
            const authService = knowledgeGraph.createEntity(testSessionId, 'class', 'AuthService');
            const tokenManager = knowledgeGraph.createEntity(testSessionId, 'class', 'TokenManager');
            const userRepo = knowledgeGraph.createEntity(testSessionId, 'class', 'UserRepository');
            const database = knowledgeGraph.createEntity(testSessionId, 'module', 'PostgreSQL');
            knowledgeGraph.createRelation(testSessionId, authService.id, 'uses', tokenManager.id);
            knowledgeGraph.createRelation(testSessionId, authService.id, 'calls', userRepo.id);
            knowledgeGraph.createRelation(testSessionId, userRepo.id, 'connects_to', database.id);
            knowledgeGraph.createRelation(testSessionId, tokenManager.id, 'generates', authService.id, 0.8);
        });
        it('should analyze entity relationships', async () => {
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'analyze',
                input: {
                    analysisType: 'relationships',
                    sessionId: testSessionId,
                },
            };
            const results = await agentCoordinator.delegate(task);
            const output = results[0].output;
            expect(output.analysis.entityCount).toBe(4);
            expect(output.analysis.relationshipTypes).toBeDefined();
            expect(output.analysis.centralNodes).toBeDefined();
            expect(output.analysis.clusters).toBeDefined();
            expect(output.recommendations).toBeInstanceOf(Array);
        });
        it('should find central nodes in graph', async () => {
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'analyze',
                input: {
                    analysisType: 'relationships',
                    sessionId: testSessionId,
                    maxDepth: 3,
                },
            };
            const results = await agentCoordinator.delegate(task);
            const output = results[0].output;
            const centralNodes = output.analysis.centralNodes;
            expect(centralNodes.length).toBeGreaterThan(0);
            expect(centralNodes[0].connections).toBeGreaterThan(0);
        });
    });
    describe('Trend Analysis', () => {
        beforeEach(() => {
            // Create items with different timestamps
            const now = new Date();
            const items = [];
            for (let i = 7; i >= 0; i--) {
                const date = new Date(now);
                date.setDate(date.getDate() - i);
                // Simulate increasing activity
                const itemCount = i === 0 ? 5 : i === 1 ? 4 : 2;
                for (let j = 0; j < itemCount; j++) {
                    items.push({
                        key: `item_${i}_${j}`,
                        value: `Activity on day ${i}`,
                        category: j % 2 === 0 ? 'task' : 'progress',
                        priority: j === 0 ? 'high' : 'normal',
                        created_at: date.toISOString(),
                    });
                }
            }
            for (const item of items) {
                db.prepare('INSERT INTO context_items (id, session_id, key, value, category, priority, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)').run((0, uuid_1.v4)(), testSessionId, item.key, item.value, item.category, item.priority, item.created_at);
            }
        });
        it('should analyze activity trends', async () => {
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'analyze',
                input: {
                    analysisType: 'trends',
                    sessionId: testSessionId,
                    timeframe: '-7 days',
                },
            };
            const results = await agentCoordinator.delegate(task);
            const output = results[0].output;
            expect(output.trends.activityTrend).toBeDefined();
            expect(output.trends.activityTrend.direction).toBe('increasing');
            expect(output.trends.categoryTrends).toBeDefined();
            expect(output.trends.predictions).toBeDefined();
        });
    });
    describe('Synthesis Operations', () => {
        beforeEach(() => {
            // Add diverse content for synthesis
            const items = [
                {
                    key: 'critical_bug',
                    value: 'Production server memory leak',
                    category: 'task',
                    priority: 'high',
                },
                {
                    key: 'auth_decision',
                    value: 'Implement OAuth2 with Google and GitHub',
                    category: 'decision',
                    priority: 'high',
                },
                {
                    key: 'api_progress',
                    value: 'Completed 80% of API endpoints',
                    category: 'progress',
                    priority: 'normal',
                },
                {
                    key: 'deploy_task',
                    value: 'Deploy to staging environment',
                    category: 'task',
                    priority: 'high',
                },
                {
                    key: 'test_progress',
                    value: 'Test coverage at 85%',
                    category: 'progress',
                    priority: 'normal',
                },
            ];
            for (const item of items) {
                db.prepare('INSERT INTO context_items (id, session_id, key, value, category, priority) VALUES (?, ?, ?, ?, ?, ?)').run((0, uuid_1.v4)(), testSessionId, item.key, item.value, item.category, item.priority);
            }
        });
        it('should create comprehensive summary', async () => {
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'synthesize',
                input: {
                    synthesisType: 'summary',
                    sessionId: testSessionId,
                    maxLength: 2000,
                },
            };
            const results = await agentCoordinator.delegate(task);
            expect(results[0].agentType).toBe('synthesizer');
            const output = results[0].output;
            expect(output.summary).toBeDefined();
            expect(output.summary).toContain('Context Summary');
            expect(output.summary).toContain('Key Decisions');
            expect(output.summary).toContain('Current Tasks');
            expect(output.summary.length).toBeLessThanOrEqual(2000);
        });
        it('should generate actionable recommendations', async () => {
            const analysisResults = {
                highPriorityCount: 3,
                contextSize: 500,
                staleTasks: false,
            };
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'synthesize',
                input: {
                    synthesisType: 'recommendations',
                    analysisResults,
                },
            };
            const results = await agentCoordinator.delegate(task);
            const output = results[0].output;
            expect(output.immediate).toBeDefined();
            expect(output.shortTerm).toBeDefined();
            expect(output.longTerm).toBeDefined();
            expect(output.warnings).toBeDefined();
        });
    });
    describe('Agent Chaining', () => {
        beforeEach(() => {
            // Setup comprehensive test data
            const items = [
                {
                    key: 'main_feature',
                    value: 'Building real-time chat system',
                    category: 'task',
                    priority: 'high',
                },
                {
                    key: 'tech_decision',
                    value: 'Use WebSockets for real-time communication',
                    category: 'decision',
                    priority: 'high',
                },
                {
                    key: 'progress_ws',
                    value: 'WebSocket server implementation complete',
                    category: 'progress',
                    priority: 'normal',
                },
                {
                    key: 'security_task',
                    value: 'Implement message encryption',
                    category: 'task',
                    priority: 'high',
                },
                {
                    key: 'scale_note',
                    value: 'Consider horizontal scaling for chat servers',
                    category: 'note',
                    priority: 'normal',
                },
            ];
            for (const item of items) {
                db.prepare('INSERT INTO context_items (id, session_id, key, value, category, priority) VALUES (?, ?, ?, ?, ?, ?)').run((0, uuid_1.v4)(), testSessionId, item.key, item.value, item.category, item.priority);
            }
        });
        it('should process analysis then synthesis chain', async () => {
            const tasks = [
                {
                    id: (0, uuid_1.v4)(),
                    type: 'analyze',
                    input: {
                        analysisType: 'comprehensive',
                        sessionId: testSessionId,
                    },
                },
                {
                    id: (0, uuid_1.v4)(),
                    type: 'synthesize',
                    input: {
                        synthesisType: 'recommendations',
                    },
                },
            ];
            const results = await agentCoordinator.processChain(tasks);
            expect(results.length).toBe(2);
            expect(results[0].agentType).toBe('analyzer');
            expect(results[1].agentType).toBe('synthesizer');
            // Second task should use first task's output
            expect(results[1].output.immediate).toBeDefined();
            expect(results[1].output.shortTerm).toBeDefined();
            expect(results[1].output.longTerm).toBeDefined();
            expect(results[1].output.warnings).toBeDefined();
            // Should have generated some recommendations
            const totalRecommendations = results[1].output.immediate.length +
                results[1].output.shortTerm.length +
                results[1].output.longTerm.length;
            expect(totalRecommendations).toBeGreaterThan(0);
        });
    });
    describe('Comprehensive Analysis', () => {
        it('should perform full system analysis', async () => {
            // Add complex data
            const items = [
                {
                    key: 'arch_decision',
                    value: 'Microservices architecture with API gateway',
                    category: 'decision',
                    priority: 'high',
                },
                {
                    key: 'auth_task',
                    value: 'Implement JWT authentication',
                    category: 'task',
                    priority: 'high',
                },
                {
                    key: 'db_progress',
                    value: 'Database schema migration complete',
                    category: 'progress',
                    priority: 'normal',
                },
                {
                    key: 'perf_note',
                    value: 'Monitor API response times',
                    category: 'note',
                    priority: 'high',
                },
            ];
            for (const item of items) {
                db.prepare('INSERT INTO context_items (id, session_id, key, value, category, priority) VALUES (?, ?, ?, ?, ?, ?)').run((0, uuid_1.v4)(), testSessionId, item.key, item.value, item.category, item.priority);
            }
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'analyze',
                input: {
                    analysisType: 'comprehensive',
                    sessionId: testSessionId,
                },
            };
            const results = await agentCoordinator.delegate(task);
            const output = results[0].output;
            expect(output.patterns).toBeDefined();
            expect(output.relationships).toBeDefined();
            expect(output.trends).toBeDefined();
            expect(output.overallInsights).toBeDefined();
            expect(output.overallInsights.length).toBeGreaterThan(0);
            expect(results[0].confidence).toBe(0.9);
        });
    });
    describe('Error Handling', () => {
        it('should handle invalid task type gracefully', async () => {
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'invalid',
                input: {},
            };
            const results = await agentCoordinator.delegate(task);
            expect(results.length).toBe(1);
            expect(results[0].output.error).toBeDefined();
            expect(results[0].confidence).toBe(0);
        });
        it('should handle missing session gracefully', async () => {
            const task = {
                id: (0, uuid_1.v4)(),
                type: 'analyze',
                input: {
                    analysisType: 'patterns',
                    sessionId: 'non-existent-session',
                },
            };
            const results = await agentCoordinator.delegate(task);
            expect(results[0].output.itemCount).toBe(0);
            expect(results[0].confidence).toBeLessThan(0.8); // Lower confidence with no data
        });
    });
});
