/**
 * @license
 * Copyright 2025 Vybestack LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { dynamicSettingsRegistry, generateDynamicToolSettings, } from './dynamicSettings.js';
// Mock DebugLogger
const { mockLog } = vi.hoisted(() => ({
    mockLog: vi.fn(),
}));
vi.mock('@vybestack/llxprt-code-core', async (importOriginal) => {
    const actual = await importOriginal();
    return {
        ...actual,
        DebugLogger: vi.fn().mockImplementation(() => ({
            log: mockLog,
        })),
    };
});
// Mock console methods to avoid noise in tests
const originalConsoleError = console.error;
const originalConsoleWarn = console.warn;
const originalConsoleDebug = console.debug;
describe('DynamicSettingsRegistry', () => {
    beforeEach(() => {
        vi.clearAllMocks();
        console.error = vi.fn();
        console.warn = vi.fn();
        console.debug = vi.fn();
        // Reset registry for each test
        dynamicSettingsRegistry.reset();
    });
    afterEach(() => {
        console.error = originalConsoleError;
        console.warn = originalConsoleWarn;
        console.debug = originalConsoleDebug;
    });
    describe('register', () => {
        it('should register settings successfully', () => {
            const settings = {
                'test.setting': {
                    type: 'boolean',
                    label: 'Test Setting',
                    category: 'Test',
                    requiresRestart: true,
                    default: true,
                    description: 'A test setting',
                    showInDialog: true,
                },
            };
            expect(() => dynamicSettingsRegistry.register(settings)).not.toThrow();
            expect(dynamicSettingsRegistry.has('test.setting')).toBe(true);
        });
        it('should throw error on duplicate registration', () => {
            const settings = {
                'test.setting': {
                    type: 'boolean',
                    label: 'Test Setting',
                    category: 'Test',
                    requiresRestart: true,
                    default: true,
                    description: 'A test setting',
                    showInDialog: true,
                },
            };
            dynamicSettingsRegistry.register(settings);
            expect(() => dynamicSettingsRegistry.register(settings)).toThrow('DynamicSettingsRegistry: Already initialized. Use reset() if needed.');
        });
        it('should validate settings structure', () => {
            const invalidSettings = {
                'invalid.setting': {
                    // Missing required fields
                    type: 'boolean',
                    // label is missing
                },
            };
            expect(() => dynamicSettingsRegistry.register(invalidSettings)).toThrow("Setting definition for key 'invalid.setting' must have a valid label");
        });
        it('should throw error for non-object settings', () => {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            expect(() => dynamicSettingsRegistry.register(null)).toThrow('Settings must be a valid object');
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            expect(() => dynamicSettingsRegistry.register(undefined)).toThrow('Settings must be a valid object');
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            expect(() => dynamicSettingsRegistry.register('string')).toThrow('Settings must be a valid object');
        });
    });
    describe('get', () => {
        beforeEach(() => {
            const settings = {
                'test.boolean': {
                    type: 'boolean',
                    label: 'Boolean Setting',
                    category: 'Test',
                    requiresRestart: false,
                    default: true,
                    description: 'A boolean setting',
                    showInDialog: true,
                },
                'test.string': {
                    type: 'string',
                    label: 'String Setting',
                    category: 'Test',
                    requiresRestart: true,
                    default: 'default',
                    description: 'A string setting',
                    showInDialog: true,
                },
            };
            dynamicSettingsRegistry.register(settings);
        });
        it('should retrieve registered settings', () => {
            const booleanSetting = dynamicSettingsRegistry.get('test.boolean');
            expect(booleanSetting).toBeDefined();
            expect(booleanSetting?.type).toBe('boolean');
            expect(booleanSetting?.label).toBe('Boolean Setting');
        });
        it('should return undefined for non-existent keys', () => {
            const nonExistent = dynamicSettingsRegistry.get('non.existent');
            expect(nonExistent).toBeUndefined();
        });
    });
    describe('has', () => {
        beforeEach(() => {
            const settings = {
                'test.setting': {
                    type: 'boolean',
                    label: 'Test Setting',
                    category: 'Test',
                    requiresRestart: true,
                    default: true,
                    description: 'A test setting',
                    showInDialog: true,
                },
            };
            dynamicSettingsRegistry.register(settings);
        });
        it('should return true for existing keys', () => {
            expect(dynamicSettingsRegistry.has('test.setting')).toBe(true);
        });
        it('should return false for non-existent keys', () => {
            expect(dynamicSettingsRegistry.has('non.existent')).toBe(false);
        });
    });
    describe('requiresRestart', () => {
        beforeEach(() => {
            const settings = {
                'restart.required': {
                    type: 'boolean',
                    label: 'Restart Required',
                    category: 'Test',
                    requiresRestart: true,
                    default: true,
                    description: 'Requires restart',
                    showInDialog: true,
                },
                'restart.notRequired': {
                    type: 'boolean',
                    label: 'No Restart Required',
                    category: 'Test',
                    requiresRestart: false,
                    default: true,
                    description: 'Does not require restart',
                    showInDialog: true,
                },
            };
            dynamicSettingsRegistry.register(settings);
        });
        it('should return true for settings that require restart', () => {
            expect(dynamicSettingsRegistry.requiresRestart('restart.required')).toBe(true);
        });
        it('should return false for settings that do not require restart', () => {
            expect(dynamicSettingsRegistry.requiresRestart('restart.notRequired')).toBe(false);
        });
        it('should return false for non-existent settings', () => {
            expect(dynamicSettingsRegistry.requiresRestart('non.existent')).toBe(false);
        });
    });
    describe('reset', () => {
        it('should reset the registry to initial state', () => {
            const settings = {
                'test.setting': {
                    type: 'boolean',
                    label: 'Test Setting',
                    category: 'Test',
                    requiresRestart: true,
                    default: true,
                    description: 'A test setting',
                    showInDialog: true,
                },
            };
            dynamicSettingsRegistry.register(settings);
            expect(dynamicSettingsRegistry.has('test.setting')).toBe(true);
            dynamicSettingsRegistry.reset();
            expect(dynamicSettingsRegistry.has('test.setting')).toBe(false);
            // Should be able to register again after reset
            expect(() => dynamicSettingsRegistry.register(settings)).not.toThrow();
        });
    });
});
describe('generateDynamicToolSettings', () => {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let mockConfig;
    const originalEnv = process.env;
    const mockRegisteredTools = [
        {
            toolClass: 'ReadFileTool',
            toolName: 'ReadFile',
            displayName: 'Read File',
            isRegistered: true,
            args: [],
        },
        {
            toolClass: 'WriteFileTool',
            toolName: 'WriteFile',
            displayName: 'Write File',
            isRegistered: true,
            args: [],
        },
        {
            toolClass: 'ShellTool',
            toolName: 'Shell',
            displayName: 'Shell Command',
            isRegistered: true,
            args: [],
        },
    ];
    const mockUnregisteredTools = [
        {
            toolClass: 'TaskTool',
            toolName: 'Task',
            displayName: 'Task',
            isRegistered: false,
            reason: 'requires profile manager and subagent manager',
            args: [],
        },
        {
            toolClass: 'ListSubagentsTool',
            toolName: 'ListSubagents',
            displayName: 'List Subagents',
            isRegistered: false,
            reason: 'requires subagent manager',
            args: [],
        },
    ];
    beforeEach(() => {
        vi.clearAllMocks();
        console.error = vi.fn();
        console.debug = vi.fn();
        process.env = { ...originalEnv }; // Reset env vars
        mockConfig = {
            getToolRegistryInfo: vi.fn(() => ({
                registered: mockRegisteredTools,
                unregistered: mockUnregisteredTools,
            })),
        };
    });
    afterEach(() => {
        console.error = originalConsoleError;
        console.debug = originalConsoleDebug;
        process.env = originalEnv;
    });
    it('should generate settings for registered tools', () => {
        const toolSettings = generateDynamicToolSettings(mockConfig);
        expect(toolSettings).toHaveProperty('ReadFile');
        expect(toolSettings).toHaveProperty('WriteFile');
        expect(toolSettings).toHaveProperty('ShellCommand');
        const readFileSetting = toolSettings.ReadFile;
        expect(readFileSetting.type).toBe('boolean');
        expect(readFileSetting.label).toBe('Read File');
        expect(readFileSetting.category).toBe('Advanced');
        expect(readFileSetting.requiresRestart).toBe(true);
        expect(readFileSetting.default).toBe(true);
        expect(readFileSetting.showInDialog).toBe(true);
    });
    it('should generate settings for unregistered tools', () => {
        const toolSettings = generateDynamicToolSettings(mockConfig);
        expect(toolSettings).toHaveProperty('Task');
        expect(toolSettings).toHaveProperty('ListSubagents');
        const taskSetting = toolSettings.Task;
        expect(taskSetting.type).toBe('boolean');
        expect(taskSetting.label).toBe('Task');
        expect(taskSetting.category).toBe('Advanced');
        expect(taskSetting.requiresRestart).toBe(true);
        expect(taskSetting.default).toBe(false); // Unregistered tools default to false
        expect(taskSetting.showInDialog).toBe(true);
        expect(taskSetting.description).toContain('unavailable: requires profile manager and subagent manager');
    });
    it('should handle tools with spaces in names correctly', () => {
        const toolSettings = generateDynamicToolSettings(mockConfig);
        // Spaces should be removed from setting keys
        expect(toolSettings).toHaveProperty('ShellCommand');
        expect(toolSettings.ShellCommand.label).toBe('Shell Command');
    });
    it('should return empty object when config is undefined', () => {
        const toolSettings = generateDynamicToolSettings(undefined);
        expect(toolSettings).toEqual({});
    });
    it('should handle empty tool registry', () => {
        mockConfig.getToolRegistryInfo.mockReturnValue({
            registered: [],
            unregistered: [],
        });
        const toolSettings = generateDynamicToolSettings(mockConfig);
        expect(toolSettings).toEqual({});
    });
    it('should handle only unregistered tools', () => {
        mockConfig.getToolRegistryInfo.mockReturnValue({
            registered: [],
            unregistered: mockUnregisteredTools,
        });
        const toolSettings = generateDynamicToolSettings(mockConfig);
        expect(Object.keys(toolSettings)).toHaveLength(2);
        expect(toolSettings).toHaveProperty('Task');
        expect(toolSettings).toHaveProperty('ListSubagents');
    });
    it('should handle tool registry errors gracefully', () => {
        const errorConfig = {
            getToolRegistryInfo: vi.fn(() => {
                throw new Error('Tool registry error');
            }),
        };
        const toolSettings = generateDynamicToolSettings(errorConfig);
        expect(toolSettings).toEqual({});
        expect(console.error).toHaveBeenCalledWith('[generateDynamicToolSettings] Error:', expect.any(Error));
    });
    it('should log basic debug information', () => {
        generateDynamicToolSettings(mockConfig);
        expect(mockLog).toHaveBeenCalledWith('Processing 3 registered and 2 unregistered tools');
        expect(mockLog).toHaveBeenCalledWith('Final toolSettings count: 5');
    });
    it('should NOT log detailed tool info when DEBUG is not verbose', () => {
        process.env.DEBUG = ''; // Ensure verbose is not set
        generateDynamicToolSettings(mockConfig);
        expect(mockLog).not.toHaveBeenCalledWith(expect.stringContaining('✅ REGISTERED'));
        expect(mockLog).not.toHaveBeenCalledWith(expect.stringContaining('🚫 UNREGISTERED'));
    });
    it('should log detailed tool info when DEBUG includes verbose', () => {
        process.env.DEBUG = 'verbose'; // Set verbose mode
        generateDynamicToolSettings(mockConfig);
        expect(mockLog).toHaveBeenCalledWith('✅ REGISTERED: Read File');
        expect(mockLog).toHaveBeenCalledWith('✅ REGISTERED: Write File');
        expect(mockLog).toHaveBeenCalledWith('✅ REGISTERED: Shell Command');
        expect(mockLog).toHaveBeenCalledWith('🚫 UNREGISTERED: Task - requires profile manager and subagent manager');
        expect(mockLog).toHaveBeenCalledWith('🚫 UNREGISTERED: List Subagents - requires subagent manager');
    });
});
//# sourceMappingURL=dynamicSettings.test.js.map