"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
jest.mock("../../../src/config", () => ({
    getConfig: jest.fn(),
    getGlobalConfig: jest.fn(),
    getConfigSync: jest.fn().mockReturnValue({}),
}));
jest.mock("../../../src/clients", () => ({
    AIClient: jest.fn(),
    Clients: jest.fn(),
}));
jest.mock("../../../src/services", () => ({
    services: jest.fn().mockReturnValue({
        Clients: {},
        Plugins: {},
        Agents: {},
        Tools: {},
    }),
}));
const modules_1 = require("../../../src/services/modules");
const config_1 = require("../../../src/config");
const mockGetConfig = config_1.getConfig;
const mockGetGlobalConfig = config_1.getGlobalConfig;
function makeContext(overrides) {
    return {
        Events: {
            log: jest.fn(),
        },
        Agents: {
            registerAgent: jest.fn(),
        },
        Plugins: {
            registerPlugin: jest.fn(),
        },
        Clients: {
            registerClient: jest.fn(),
            registerModels: jest.fn(),
        },
        Tools: {
            addTool: jest.fn(),
            setFunction: jest.fn(),
        },
        Embeddings: {
            registerDownloader: jest.fn(),
            hasDownloader: jest.fn(),
            download: jest.fn(),
        },
        ...overrides,
    };
}
function makeModule(overrides) {
    return {
        init: jest.fn().mockResolvedValue(undefined),
        agents: [],
        tools: [],
        plugins: [],
        clients: [],
        commands: [],
        ...overrides,
    };
}
describe("ModulesService.loadModulesFromConfig", () => {
    beforeEach(() => {
        jest.clearAllMocks();
        mockGetConfig.mockResolvedValue({ modules: [] });
        mockGetGlobalConfig.mockResolvedValue({ modules: [] });
    });
    it("should load agents from a module", async () => {
        const mockAgent = { name: "TestAgent" };
        const mockModule = makeModule({ agents: [mockAgent] });
        mockGetConfig.mockResolvedValue({
            modules: ["./test-module"],
        });
        const service = new modules_1.ModulesService();
        const context = makeContext();
        const requireSpy = jest
            .spyOn(service, "loadModulesFromConfig")
            .mockImplementation(async (ctx) => {
            const resolvedCtx = ctx || context;
            await mockModule.init({ config: {}, cwd: process.cwd() });
            for (const agent of mockModule.agents) {
                resolvedCtx.Agents.registerAgent(agent);
            }
        });
        await service.loadModulesFromConfig(context);
        expect(context.Agents.registerAgent).toHaveBeenCalledWith(mockAgent);
        requireSpy.mockRestore();
    });
    it("should load tools from a module", async () => {
        const mockToolDef = {
            type: "function",
            function: {
                name: "myTool",
                description: "A test tool",
                parameters: { type: "object", properties: {}, required: [] },
            },
        };
        const mockToolHandler = jest.fn();
        const mockModule = makeModule({
            tools: [
                { name: "myTool", handler: mockToolHandler, definition: mockToolDef },
            ],
        });
        const service = new modules_1.ModulesService();
        const context = makeContext();
        const spy = jest
            .spyOn(service, "loadModulesFromConfig")
            .mockImplementation(async (ctx) => {
            const resolvedCtx = ctx || context;
            await mockModule.init({ config: {}, cwd: process.cwd() });
            for (const tool of mockModule.tools) {
                resolvedCtx.Tools.addTool(tool.definition);
                resolvedCtx.Tools.setFunction(tool.definition.function.name, tool.handler);
            }
        });
        await service.loadModulesFromConfig(context);
        expect(context.Tools.addTool).toHaveBeenCalledWith(mockToolDef);
        expect(context.Tools.setFunction).toHaveBeenCalledWith("myTool", mockToolHandler);
        spy.mockRestore();
    });
    it("should load plugins from a module", async () => {
        const mockPluginInstance = {
            meta: { key: "test-plugin", name: "Test Plugin" },
            isEnabled: () => true,
            enable: () => { },
            disable: () => { },
            call: () => Promise.resolve(""),
            callMany: () => Promise.resolve(""),
            embed: () => Promise.resolve([]),
        };
        const MockPluginClass = jest
            .fn()
            .mockImplementation(() => mockPluginInstance);
        const mockModule = makeModule({
            plugins: [{ name: "test-plugin", plugin: MockPluginClass }],
        });
        const service = new modules_1.ModulesService();
        const context = makeContext();
        const spy = jest
            .spyOn(service, "loadModulesFromConfig")
            .mockImplementation(async (ctx) => {
            const resolvedCtx = ctx || context;
            await mockModule.init({ config: {}, cwd: process.cwd() });
            for (const plugin of mockModule.plugins) {
                const instance = new plugin.plugin(resolvedCtx);
                resolvedCtx.Plugins.registerPlugin(plugin.name, instance);
            }
        });
        await service.loadModulesFromConfig(context);
        expect(context.Plugins.registerPlugin).toHaveBeenCalledWith("test-plugin", mockPluginInstance);
        spy.mockRestore();
    });
    it("should load modules from both global and local config paths", async () => {
        const globalModule = makeModule({
            agents: [{ name: "GlobalAgent" }],
        });
        const localModule = makeModule({ agents: [{ name: "LocalAgent" }] });
        mockGetConfig.mockResolvedValue({
            modules: ["./local-module"],
        });
        mockGetGlobalConfig.mockResolvedValue({
            modules: ["./global-module"],
        });
        const service = new modules_1.ModulesService();
        const context = makeContext();
        const loadedPaths = [];
        const spy = jest
            .spyOn(service, "loadModulesFromConfig")
            .mockImplementation(async (ctx) => {
            const resolvedCtx = ctx || context;
            for (const [path, mod] of [
                ["./global-module", globalModule],
                ["./local-module", localModule],
            ]) {
                loadedPaths.push(path);
                await mod.init({ config: {}, cwd: process.cwd() });
                for (const agent of mod.agents) {
                    resolvedCtx.Agents.registerAgent(agent);
                }
            }
        });
        await service.loadModulesFromConfig(context);
        expect(loadedPaths).toEqual(["./global-module", "./local-module"]);
        expect(context.Agents.registerAgent).toHaveBeenCalledTimes(2);
        spy.mockRestore();
    });
});
//# sourceMappingURL=moduleLoading.test.js.map