/**
 * @license
 * Copyright 2026 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mapToDisplay } from './toolMapping.js';
import { CoreToolCallStatus, } from '@google/gemini-cli-core';
import { ToolCallStatus, mapCoreStatusToDisplayStatus } from '../types.js';
describe('toolMapping', () => {
    beforeEach(() => {
        vi.clearAllMocks();
    });
    describe('mapCoreStatusToDisplayStatus', () => {
        it.each([
            [CoreToolCallStatus.Validating, ToolCallStatus.Pending],
            [CoreToolCallStatus.AwaitingApproval, ToolCallStatus.Confirming],
            [CoreToolCallStatus.Executing, ToolCallStatus.Executing],
            [CoreToolCallStatus.Success, ToolCallStatus.Success],
            [CoreToolCallStatus.Cancelled, ToolCallStatus.Canceled],
            [CoreToolCallStatus.Error, ToolCallStatus.Error],
            [CoreToolCallStatus.Scheduled, ToolCallStatus.Pending],
        ])('maps %s to %s', (coreStatus, expectedDisplayStatus) => {
            expect(mapCoreStatusToDisplayStatus(coreStatus)).toBe(expectedDisplayStatus);
        });
        it('throws error for unknown status due to checkExhaustive', () => {
            expect(() => mapCoreStatusToDisplayStatus('unknown_status')).toThrow('unexpected value unknown_status!');
        });
    });
    describe('mapToDisplay', () => {
        const mockRequest = {
            callId: 'call-1',
            name: 'test_tool',
            args: { arg1: 'val1' },
            isClientInitiated: false,
            prompt_id: 'p1',
        };
        const mockTool = {
            name: 'test_tool',
            displayName: 'Test Tool',
            isOutputMarkdown: true,
        };
        const mockInvocation = {
            getDescription: () => 'Calling test_tool with args...',
        };
        const mockResponse = {
            callId: 'call-1',
            responseParts: [],
            resultDisplay: 'Success output',
            error: undefined,
            errorType: undefined,
        };
        it('handles a single tool call input', () => {
            const toolCall = {
                status: CoreToolCallStatus.Scheduled,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
            };
            const result = mapToDisplay(toolCall);
            expect(result.type).toBe('tool_group');
            expect(result.tools).toHaveLength(1);
            expect(result.tools[0]?.callId).toBe('call-1');
        });
        it('handles an array of tool calls', () => {
            const toolCall1 = {
                status: CoreToolCallStatus.Scheduled,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
            };
            const toolCall2 = {
                status: CoreToolCallStatus.Scheduled,
                request: { ...mockRequest, callId: 'call-2' },
                tool: mockTool,
                invocation: mockInvocation,
            };
            const result = mapToDisplay([toolCall1, toolCall2]);
            expect(result.tools).toHaveLength(2);
            expect(result.tools[0]?.callId).toBe('call-1');
            expect(result.tools[1]?.callId).toBe('call-2');
        });
        it('maps successful tool call properties correctly', () => {
            const toolCall = {
                status: CoreToolCallStatus.Success,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
                response: {
                    ...mockResponse,
                    outputFile: '/tmp/output.txt',
                },
            };
            const result = mapToDisplay(toolCall);
            const displayTool = result.tools[0];
            expect(displayTool).toEqual(expect.objectContaining({
                callId: 'call-1',
                name: 'Test Tool',
                description: 'Calling test_tool with args...',
                renderOutputAsMarkdown: true,
                status: CoreToolCallStatus.Success,
                resultDisplay: 'Success output',
                outputFile: '/tmp/output.txt',
            }));
        });
        it('maps executing tool call properties correctly with live output and ptyId', () => {
            const toolCall = {
                status: CoreToolCallStatus.Executing,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
                liveOutput: 'Loading...',
                pid: 12345,
            };
            const result = mapToDisplay(toolCall);
            const displayTool = result.tools[0];
            expect(displayTool.status).toBe(CoreToolCallStatus.Executing);
            expect(displayTool.resultDisplay).toBe('Loading...');
            expect(displayTool.ptyId).toBe(12345);
        });
        it('maps awaiting_approval tool call properties with correlationId', () => {
            const confirmationDetails = {
                type: 'exec',
                title: 'Confirm Exec',
                command: 'ls',
                rootCommand: 'ls',
                rootCommands: ['ls'],
                onConfirm: vi.fn(),
            };
            const toolCall = {
                status: CoreToolCallStatus.AwaitingApproval,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
                confirmationDetails,
                correlationId: 'corr-id-123',
            };
            const result = mapToDisplay(toolCall);
            const displayTool = result.tools[0];
            expect(displayTool.status).toBe(CoreToolCallStatus.AwaitingApproval);
            expect(displayTool.confirmationDetails).toEqual(confirmationDetails);
        });
        it('maps correlationId and serializable confirmation details', () => {
            const serializableDetails = {
                type: 'edit',
                title: 'Confirm Edit',
                fileName: 'file.txt',
                filePath: '/path/file.txt',
                fileDiff: 'diff',
                originalContent: 'old',
                newContent: 'new',
            };
            const toolCall = {
                status: CoreToolCallStatus.AwaitingApproval,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
                confirmationDetails: serializableDetails,
                correlationId: 'corr-123',
            };
            const result = mapToDisplay(toolCall);
            const displayTool = result.tools[0];
            expect(displayTool.correlationId).toBe('corr-123');
            expect(displayTool.confirmationDetails).toEqual(serializableDetails);
        });
        it('maps error tool call missing tool definition', () => {
            // e.g. "TOOL_NOT_REGISTERED" errors
            const toolCall = {
                status: CoreToolCallStatus.Error,
                request: mockRequest, // name: 'test_tool'
                response: { ...mockResponse, resultDisplay: 'Tool not found' },
                // notice: no `tool` or `invocation` defined here
            };
            const result = mapToDisplay(toolCall);
            const displayTool = result.tools[0];
            expect(displayTool.status).toBe(CoreToolCallStatus.Error);
            expect(displayTool.name).toBe('test_tool'); // falls back to request.name
            expect(displayTool.description).toBe('{"arg1":"val1"}'); // falls back to stringified args
            expect(displayTool.resultDisplay).toBe('Tool not found');
            expect(displayTool.renderOutputAsMarkdown).toBe(false);
        });
        it('maps cancelled tool call properties correctly', () => {
            const toolCall = {
                status: CoreToolCallStatus.Cancelled,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
                response: {
                    ...mockResponse,
                    resultDisplay: 'User cancelled', // Could be diff output for edits
                },
            };
            const result = mapToDisplay(toolCall);
            const displayTool = result.tools[0];
            expect(displayTool.status).toBe(CoreToolCallStatus.Cancelled);
            expect(displayTool.resultDisplay).toBe('User cancelled');
        });
        it('propagates borderTop and borderBottom options correctly', () => {
            const toolCall = {
                status: CoreToolCallStatus.Scheduled,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
            };
            const result = mapToDisplay(toolCall, {
                borderTop: true,
                borderBottom: false,
            });
            expect(result.borderTop).toBe(true);
            expect(result.borderBottom).toBe(false);
        });
        it('maps raw progress and progressTotal from Executing calls', () => {
            const toolCall = {
                status: CoreToolCallStatus.Executing,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
                progressMessage: 'Downloading...',
                progress: 5,
                progressTotal: 10,
            };
            const result = mapToDisplay(toolCall);
            const displayTool = result.tools[0];
            expect(displayTool.progress).toBe(5);
            expect(displayTool.progressTotal).toBe(10);
            expect(displayTool.progressMessage).toBe('Downloading...');
        });
        it('leaves progress fields undefined for non-Executing calls', () => {
            const toolCall = {
                status: CoreToolCallStatus.Success,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
                response: mockResponse,
            };
            const result = mapToDisplay(toolCall);
            const displayTool = result.tools[0];
            expect(displayTool.progress).toBeUndefined();
            expect(displayTool.progressTotal).toBeUndefined();
        });
        it('sets resultDisplay to undefined for pre-execution statuses', () => {
            const toolCall = {
                status: CoreToolCallStatus.Scheduled,
                request: mockRequest,
                tool: mockTool,
                invocation: mockInvocation,
            };
            const result = mapToDisplay(toolCall);
            expect(result.tools[0].resultDisplay).toBeUndefined();
            expect(result.tools[0].status).toBe(CoreToolCallStatus.Scheduled);
        });
        it('propagates originalRequestName correctly', () => {
            const toolCall = {
                status: CoreToolCallStatus.Scheduled,
                request: {
                    ...mockRequest,
                    originalRequestName: 'original_tool',
                },
                tool: mockTool,
                invocation: mockInvocation,
            };
            const result = mapToDisplay(toolCall);
            expect(result.tools[0].originalRequestName).toBe('original_tool');
        });
    });
});
//# sourceMappingURL=toolMapping.test.js.map