/**
 * AdapterRegistry 测试
 */
import { EventEmitter } from 'node:events';
import { beforeEach, describe, expect, it } from 'vitest';
import { AdapterRegistry } from '../adapter/AdapterRegistry.js';
import { registerSdkProviders } from '../adapter/SdkProviderSpi.js';
import { CodexSdkAdapter } from './CodexSdkAdapter.js';
// 创建测试用的 Mock Adapter
class MockAdapter extends EventEmitter {
    constructor() {
        super(...arguments);
        this.providerId = 'mock-provider';
        this.displayName = 'Mock Provider';
    }
    async startSession(sessionId, _config) {
        this.emit('status-change', sessionId, 'running');
    }
    async sendMessage(_sessionId, _message) { }
    async sendConfirmation(_sessionId, _accept) { }
    async abortCurrentTurn(_sessionId) { }
    async terminateSession(_sessionId) { }
    async resumeSession(_sessionId, _providerSessionId, _config) { }
    getConversation(_sessionId) {
        return [];
    }
    hasSession(_sessionId) {
        return false;
    }
    getProviderSessionId(_sessionId) {
        return undefined;
    }
    getSessionStatus(_sessionId) {
        return undefined;
    }
    cleanup() { }
}
describe('AdapterRegistry', () => {
    let registry;
    beforeEach(() => {
        registry = new AdapterRegistry();
    });
    describe('register', () => {
        it('should register an adapter', () => {
            const adapter = new MockAdapter();
            registry.register(adapter);
            expect(registry.has('mock-provider')).toBe(true);
        });
        it('should throw error when registering duplicate providerId', () => {
            const adapter1 = new MockAdapter();
            const adapter2 = new MockAdapter();
            registry.register(adapter1);
            expect(() => registry.register(adapter2)).toThrow('Adapter already registered');
        });
    });
    describe('get', () => {
        it('should return registered adapter', () => {
            const adapter = new MockAdapter();
            registry.register(adapter);
            const result = registry.get('mock-provider');
            expect(result).toBe(adapter);
        });
        it('should throw error when adapter not found', () => {
            expect(() => registry.get('non-existent')).toThrow('No adapter registered');
        });
        it('should return registered codex adapter', () => {
            const adapter = new CodexSdkAdapter();
            registry.register(adapter);
            const result = registry.get('codex');
            expect(result).toBe(adapter);
            expect(registry.has('codex')).toBe(true);
        });
    });
    describe('has', () => {
        it('should return true for registered adapter', () => {
            const adapter = new MockAdapter();
            registry.register(adapter);
            expect(registry.has('mock-provider')).toBe(true);
        });
        it('should return false for non-existent adapter', () => {
            expect(registry.has('non-existent')).toBe(false);
        });
    });
    describe('getRegisteredIds', () => {
        it('should return all registered provider IDs', () => {
            const adapter = new MockAdapter();
            registry.register(adapter);
            expect(registry.getRegisteredIds()).toContain('mock-provider');
        });
        it('should return empty array when no adapters registered', () => {
            expect(registry.getRegisteredIds()).toEqual([]);
        });
    });
    describe('SDK provider SPI', () => {
        it('registers built-in SDK providers through one extension point', () => {
            registerSdkProviders(registry, () => { });
            expect(registry.getRegisteredIds().sort()).toEqual(['claude-code', 'codex', 'opencode']);
            expect(registry.get('codex').providerId).toBe('codex');
        });
    });
    describe('cleanup', () => {
        it('should clear all adapters', () => {
            const adapter = new MockAdapter();
            registry.register(adapter);
            registry.cleanup();
            expect(registry.getRegisteredIds()).toEqual([]);
        });
    });
});
