/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { SubagentToolWrapper } from './subagent-tool-wrapper.js';
import { LocalSubagentInvocation } from './local-invocation.js';
import { makeFakeConfig } from '../test-utils/config.js';
import { Kind } from '../tools/tools.js';
import { createMockMessageBus } from '../test-utils/mock-message-bus.js';
// Mock dependencies to isolate the SubagentToolWrapper class
vi.mock('./local-invocation.js');
const MockedLocalSubagentInvocation = vi.mocked(LocalSubagentInvocation);
// Define reusable test data
let mockConfig;
let mockMessageBus;
const mockDefinition = {
    kind: 'local',
    name: 'TestAgent',
    displayName: 'Test Agent Display Name',
    description: 'An agent for testing.',
    inputConfig: {
        inputSchema: {
            type: 'object',
            properties: {
                goal: { type: 'string', description: 'The goal.' },
                priority: {
                    type: 'number',
                    description: 'The priority.',
                },
            },
            required: ['goal'],
        },
    },
    modelConfig: {
        model: 'gemini-test-model',
        generateContentConfig: {
            temperature: 0,
            topP: 1,
        },
    },
    runConfig: { maxTimeMinutes: 5 },
    promptConfig: { systemPrompt: 'You are a test agent.' },
};
describe('SubagentToolWrapper', () => {
    beforeEach(() => {
        vi.clearAllMocks();
        mockConfig = makeFakeConfig();
        mockMessageBus = createMockMessageBus();
    });
    describe('constructor', () => {
        it('should correctly configure the tool properties from the agent definition', () => {
            const wrapper = new SubagentToolWrapper(mockDefinition, mockConfig, mockMessageBus);
            expect(wrapper.name).toBe(mockDefinition.name);
            expect(wrapper.displayName).toBe(mockDefinition.displayName);
            expect(wrapper.description).toBe(mockDefinition.description);
            expect(wrapper.kind).toBe(Kind.Agent);
            expect(wrapper.isOutputMarkdown).toBe(true);
            expect(wrapper.canUpdateOutput).toBe(true);
        });
        it('should fall back to the agent name for displayName if it is not provided', () => {
            const definitionWithoutDisplayName = {
                ...mockDefinition,
                displayName: undefined,
            };
            const wrapper = new SubagentToolWrapper(definitionWithoutDisplayName, mockConfig, mockMessageBus);
            expect(wrapper.displayName).toBe(definitionWithoutDisplayName.name);
        });
        it('should generate a valid tool schema using the definition and converted schema', () => {
            const wrapper = new SubagentToolWrapper(mockDefinition, mockConfig, mockMessageBus);
            const schema = wrapper.schema;
            expect(schema.name).toBe(mockDefinition.name);
            expect(schema.description).toBe(mockDefinition.description);
            expect(schema.parametersJsonSchema).toEqual(mockDefinition.inputConfig.inputSchema);
        });
    });
    describe('createInvocation', () => {
        it('should create a LocalSubagentInvocation with the correct parameters', () => {
            const wrapper = new SubagentToolWrapper(mockDefinition, mockConfig, mockMessageBus);
            const params = { goal: 'Test the invocation', priority: 1 };
            // The public `build` method calls the protected `createInvocation` after validation
            const invocation = wrapper.build(params);
            expect(invocation).toBeInstanceOf(LocalSubagentInvocation);
            expect(MockedLocalSubagentInvocation).toHaveBeenCalledExactlyOnceWith(mockDefinition, mockConfig, params, mockMessageBus, mockDefinition.name, mockDefinition.displayName);
        });
        it('should pass the messageBus to the LocalSubagentInvocation constructor', () => {
            const specificMessageBus = {
                publish: vi.fn(),
                subscribe: vi.fn(),
                unsubscribe: vi.fn(),
            };
            const wrapper = new SubagentToolWrapper(mockDefinition, mockConfig, specificMessageBus);
            const params = { goal: 'Test the invocation', priority: 1 };
            wrapper.build(params);
            expect(MockedLocalSubagentInvocation).toHaveBeenCalledWith(mockDefinition, mockConfig, params, specificMessageBus, mockDefinition.name, mockDefinition.displayName);
        });
        it('should throw a validation error for invalid parameters before creating an invocation', () => {
            const wrapper = new SubagentToolWrapper(mockDefinition, mockConfig, mockMessageBus);
            // Missing the required 'goal' parameter
            const invalidParams = { priority: 1 };
            // The `build` method in the base class performs JSON schema validation
            // before calling the protected `createInvocation` method.
            expect(() => wrapper.build(invalidParams)).toThrow("params must have required property 'goal'");
            expect(MockedLocalSubagentInvocation).not.toHaveBeenCalled();
        });
    });
});
//# sourceMappingURL=subagent-tool-wrapper.test.js.map