import { describe, it, expect } from 'vitest';
import { BeforeInvocationEvent } from '../../hooks/events.js';
import { ToolRegistry } from '../../registry/tool-registry.js';
import { createRandomTool } from '../../__fixtures__/tool-helpers.js';
/**
 * Concrete implementation of Plugin for testing purposes.
 */
class TestPlugin {
    callbacks = [];
    get name() {
        return 'test-plugin';
    }
    initAgent(agent) {
        agent.addHook(BeforeInvocationEvent, () => {
            // No-op for testing
        });
    }
}
/**
 * Plugin with custom name for testing.
 */
class CustomNamePlugin {
    _name;
    constructor(name) {
        this._name = name;
    }
    get name() {
        return this._name;
    }
    initAgent(_agent) { }
}
/**
 * Plugin with initAgent implementation for testing.
 */
class InitializablePlugin {
    initialized = false;
    get name() {
        return 'initializable-plugin';
    }
    initAgent(_agent) {
        this.initialized = true;
    }
}
describe('Plugin', () => {
    describe('name', () => {
        it('returns the plugin name', () => {
            const plugin = new TestPlugin();
            expect(plugin.name).toBe('test-plugin');
        });
        it('supports custom names via constructor', () => {
            const plugin = new CustomNamePlugin('my-custom-plugin');
            expect(plugin.name).toBe('my-custom-plugin');
        });
    });
    describe('initAgent', () => {
        it('registers callbacks via agent.addHook', () => {
            const plugin = new TestPlugin();
            const callbacks = [];
            const mockAgent = {
                addHook: (eventType, callback) => {
                    callbacks.push({
                        eventType: eventType,
                        callback: callback,
                    });
                    return () => { };
                },
                toolRegistry: new ToolRegistry(),
            };
            plugin.initAgent(mockAgent);
            expect(callbacks).toHaveLength(1);
            expect(callbacks[0]?.eventType).toBe(BeforeInvocationEvent);
        });
        it('has a no-op default when not overridden', () => {
            const plugin = new CustomNamePlugin('test');
            const mockAgent = {
                addHook: () => () => { },
                toolRegistry: new ToolRegistry(),
            };
            // Should not throw and return undefined
            const result = plugin.initAgent(mockAgent);
            expect(result).toBeUndefined();
        });
        it('can be implemented for custom initialization', () => {
            const plugin = new InitializablePlugin();
            const mockAgent = {
                addHook: () => () => { },
                toolRegistry: new ToolRegistry(),
            };
            expect(plugin.initialized).toBe(false);
            plugin.initAgent(mockAgent);
            expect(plugin.initialized).toBe(true);
        });
    });
    describe('getTools', () => {
        it('is optional — plugins without getTools are valid', () => {
            const plugin = new TestPlugin();
            expect(plugin.getTools).toBeUndefined();
        });
        it('can be implemented to provide tools', () => {
            const mockTool = createRandomTool();
            class ToolPlugin {
                get name() {
                    return 'tool-plugin';
                }
                initAgent(_agent) { }
                getTools() {
                    return [mockTool];
                }
            }
            expect(new ToolPlugin().getTools()).toStrictEqual([mockTool]);
        });
    });
});
//# sourceMappingURL=plugin.test.js.map