
import {
    AgentEngine,
    IAgent,
    ErrorClassifier,
    ErrorType,
    MissionState
} from '../src/lib/engine';
import { AgentDataValidator } from '../src/lib/diagnostics';
import * as path from 'path';
import * as fs from 'fs';

describe('ConnectAI Resilience v4.0 Validation', () => {
    
    describe('Enhanced Error Classification', () => {
        test('GPU OOM (out of memory) should be classified as TRANSIENT', () => {
            const error = new Error('Ollama error: GPU out of memory, failed to allocate weights');
            const result = ErrorClassifier.classify(error);
            expect(result.type).toBe(ErrorType.TRANSIENT);
            expect(result.rule.action).toBe('retry');
        });

        test('Context length exceeded should be classified as PERMANENT', () => {
            const error = new Error('Validation failed: context_length_exceeded for model gemini-pro');
            const result = ErrorClassifier.classify(error);
            expect(result.type).toBe(ErrorType.PERMANENT);
            expect(result.rule.action).toBe('fail_with_message');
        });

        test('Safety filter triggers should be classified as PERMANENT', () => {
            const error = new Error('Response blocked by safety_filter: harmful content detected');
            const result = ErrorClassifier.classify(error);
            expect(result.type).toBe(ErrorType.PERMANENT);
        });

        test('500 Internal Server Error should be classified as TRANSIENT', () => {
            const error = new Error('HTTP 500: Internal Server Error');
            const result = ErrorClassifier.classify(error);
            expect(result.type).toBe(ErrorType.TRANSIENT);
        });
    });

    describe('Safe Pre-Failure Audit', () => {
        class MockPermanentOOMAgent implements IAgent {
            async execute(): Promise<string> {
                // 이 에러는 패턴상 PERMANENT로 분류되도록 유도 (테스트용)
                throw new Error('404: model not found');
            }
        }

        test('Permanent error should trigger audit without crashing', async () => {
            const engine = new AgentEngine(
                new MockPermanentOOMAgent(),
                {} as IAgent,
                {} as IAgent
            );

            const state = new MissionState('audit_test_mission');
            const input = 'This is a test input that should be audited upon failure.';
            
            // audit 메서드가 에러를 던지지 않는지 확인
            const auditResult = AgentDataValidator.audit('Planner', input);
            expect(auditResult).toHaveProperty('score');
            expect(auditResult).toHaveProperty('issues');
            
            // 실제 resilientExecute 흐름에서 에러가 전파되는지 확인
            await expect((engine as any).resilientExecute(
                state,
                new MockPermanentOOMAgent(),
                'TestAgent',
                input,
                'context',
                new AbortController().signal,
                () => {}
            )).rejects.toThrow(/TestAgent/);
        });

        test('Audit should handle empty input gracefully', () => {
            const result = AgentDataValidator.audit('Tester', '');
            expect(result.score).toBe(0);
            expect(result.issues).toContain('데이터가 완전히 비어 있음');
        });
    });
});
