/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect } from 'vitest';
import { getResponseTextFromParts, getFunctionCalls, getFunctionCallsFromParts, getFunctionCallsAsJson, getFunctionCallsFromPartsAsJson, getStructuredResponse, getStructuredResponseFromParts, } from './generateContentResponseUtilities.js';
import { FinishReason } from '@google/genai';
const mockTextPart = (text) => ({ text });
const mockFunctionCallPart = (name, args) => ({
    functionCall: { name, args: args ?? {} },
});
const mockResponse = (parts, finishReason = FinishReason.STOP, safetyRatings = []) => ({
    candidates: [
        {
            content: {
                parts,
                role: 'model',
            },
            index: 0,
            finishReason,
            safetyRatings,
        },
    ],
    promptFeedback: {
        safetyRatings: [],
    },
    text: undefined,
    data: undefined,
    functionCalls: undefined,
    executableCode: undefined,
    codeExecutionResult: undefined,
});
const minimalMockResponse = (candidates) => ({
    candidates,
    promptFeedback: { safetyRatings: [] },
    text: undefined,
    data: undefined,
    functionCalls: undefined,
    executableCode: undefined,
    codeExecutionResult: undefined,
});
describe('generateContentResponseUtilities', () => {
    describe('getResponseTextFromParts', () => {
        it('should return undefined for no parts', () => {
            expect(getResponseTextFromParts([])).toBeUndefined();
        });
        it('should extract text from a single text part', () => {
            expect(getResponseTextFromParts([mockTextPart('Hello')])).toBe('Hello');
        });
        it('should concatenate text from multiple text parts', () => {
            expect(getResponseTextFromParts([
                mockTextPart('Hello '),
                mockTextPart('World'),
            ])).toBe('Hello World');
        });
        it('should ignore function call parts', () => {
            expect(getResponseTextFromParts([
                mockTextPart('Hello '),
                mockFunctionCallPart('testFunc'),
                mockTextPart('World'),
            ])).toBe('Hello World');
        });
        it('should return undefined if only function call parts exist', () => {
            expect(getResponseTextFromParts([
                mockFunctionCallPart('testFunc'),
                mockFunctionCallPart('anotherFunc'),
            ])).toBeUndefined();
        });
    });
    describe('getFunctionCalls', () => {
        it('should return undefined for no candidates', () => {
            expect(getFunctionCalls(minimalMockResponse(undefined))).toBeUndefined();
        });
        it('should return undefined for empty candidates array', () => {
            expect(getFunctionCalls(minimalMockResponse([]))).toBeUndefined();
        });
        it('should return undefined for no parts', () => {
            const response = mockResponse([]);
            expect(getFunctionCalls(response)).toBeUndefined();
        });
        it('should extract a single function call', () => {
            const func = { name: 'testFunc', args: { a: 1 } };
            const response = mockResponse([
                mockFunctionCallPart(func.name, func.args),
            ]);
            expect(getFunctionCalls(response)).toEqual([func]);
        });
        it('should extract multiple function calls', () => {
            const func1 = { name: 'testFunc1', args: { a: 1 } };
            const func2 = { name: 'testFunc2', args: { b: 2 } };
            const response = mockResponse([
                mockFunctionCallPart(func1.name, func1.args),
                mockFunctionCallPart(func2.name, func2.args),
            ]);
            expect(getFunctionCalls(response)).toEqual([func1, func2]);
        });
        it('should ignore text parts', () => {
            const func = { name: 'testFunc', args: { a: 1 } };
            const response = mockResponse([
                mockTextPart('Some text'),
                mockFunctionCallPart(func.name, func.args),
                mockTextPart('More text'),
            ]);
            expect(getFunctionCalls(response)).toEqual([func]);
        });
        it('should return undefined if only text parts exist', () => {
            const response = mockResponse([
                mockTextPart('Some text'),
                mockTextPart('More text'),
            ]);
            expect(getFunctionCalls(response)).toBeUndefined();
        });
    });
    describe('getFunctionCallsFromParts', () => {
        it('should return undefined for no parts', () => {
            expect(getFunctionCallsFromParts([])).toBeUndefined();
        });
        it('should extract a single function call', () => {
            const func = { name: 'testFunc', args: { a: 1 } };
            expect(getFunctionCallsFromParts([mockFunctionCallPart(func.name, func.args)])).toEqual([func]);
        });
        it('should extract multiple function calls', () => {
            const func1 = { name: 'testFunc1', args: { a: 1 } };
            const func2 = { name: 'testFunc2', args: { b: 2 } };
            expect(getFunctionCallsFromParts([
                mockFunctionCallPart(func1.name, func1.args),
                mockFunctionCallPart(func2.name, func2.args),
            ])).toEqual([func1, func2]);
        });
        it('should ignore text parts', () => {
            const func = { name: 'testFunc', args: { a: 1 } };
            expect(getFunctionCallsFromParts([
                mockTextPart('Some text'),
                mockFunctionCallPart(func.name, func.args),
                mockTextPart('More text'),
            ])).toEqual([func]);
        });
        it('should return undefined if only text parts exist', () => {
            expect(getFunctionCallsFromParts([
                mockTextPart('Some text'),
                mockTextPart('More text'),
            ])).toBeUndefined();
        });
    });
    describe('getFunctionCallsAsJson', () => {
        it('should return JSON string of function calls', () => {
            const func1 = { name: 'testFunc1', args: { a: 1 } };
            const func2 = { name: 'testFunc2', args: { b: 2 } };
            const response = mockResponse([
                mockFunctionCallPart(func1.name, func1.args),
                mockTextPart('text in between'),
                mockFunctionCallPart(func2.name, func2.args),
            ]);
            const expectedJson = JSON.stringify([func1, func2], null, 2);
            expect(getFunctionCallsAsJson(response)).toBe(expectedJson);
        });
        it('should return undefined if no function calls', () => {
            const response = mockResponse([mockTextPart('Hello')]);
            expect(getFunctionCallsAsJson(response)).toBeUndefined();
        });
    });
    describe('getFunctionCallsFromPartsAsJson', () => {
        it('should return JSON string of function calls from parts', () => {
            const func1 = { name: 'testFunc1', args: { a: 1 } };
            const func2 = { name: 'testFunc2', args: { b: 2 } };
            const parts = [
                mockFunctionCallPart(func1.name, func1.args),
                mockTextPart('text in between'),
                mockFunctionCallPart(func2.name, func2.args),
            ];
            const expectedJson = JSON.stringify([func1, func2], null, 2);
            expect(getFunctionCallsFromPartsAsJson(parts)).toBe(expectedJson);
        });
        it('should return undefined if no function calls in parts', () => {
            const parts = [mockTextPart('Hello')];
            expect(getFunctionCallsFromPartsAsJson(parts)).toBeUndefined();
        });
    });
    describe('getStructuredResponse', () => {
        it('should return only text if only text exists', () => {
            const response = mockResponse([mockTextPart('Hello World')]);
            expect(getStructuredResponse(response)).toBe('Hello World');
        });
        it('should return only function call JSON if only function calls exist', () => {
            const func = { name: 'testFunc', args: { data: 'payload' } };
            const response = mockResponse([
                mockFunctionCallPart(func.name, func.args),
            ]);
            const expectedJson = JSON.stringify([func], null, 2);
            expect(getStructuredResponse(response)).toBe(expectedJson);
        });
        it('should return text and function call JSON if both exist', () => {
            const text = 'Consider this data:';
            const func = { name: 'processData', args: { item: 42 } };
            const response = mockResponse([
                mockTextPart(text),
                mockFunctionCallPart(func.name, func.args),
            ]);
            const expectedJson = JSON.stringify([func], null, 2);
            expect(getStructuredResponse(response)).toBe(`${text}\n${expectedJson}`);
        });
        it('should return undefined if neither text nor function calls exist', () => {
            const response = mockResponse([]);
            expect(getStructuredResponse(response)).toBeUndefined();
        });
    });
    describe('getStructuredResponseFromParts', () => {
        it('should return only text if only text exists in parts', () => {
            const parts = [mockTextPart('Hello World')];
            expect(getStructuredResponseFromParts(parts)).toBe('Hello World');
        });
        it('should return only function call JSON if only function calls exist in parts', () => {
            const func = { name: 'testFunc', args: { data: 'payload' } };
            const parts = [mockFunctionCallPart(func.name, func.args)];
            const expectedJson = JSON.stringify([func], null, 2);
            expect(getStructuredResponseFromParts(parts)).toBe(expectedJson);
        });
        it('should return text and function call JSON if both exist in parts', () => {
            const text = 'Consider this data:';
            const func = { name: 'processData', args: { item: 42 } };
            const parts = [
                mockTextPart(text),
                mockFunctionCallPart(func.name, func.args),
            ];
            const expectedJson = JSON.stringify([func], null, 2);
            expect(getStructuredResponseFromParts(parts)).toBe(`${text}\n${expectedJson}`);
        });
        it('should return undefined if neither text nor function calls exist in parts', () => {
            const parts = [];
            expect(getStructuredResponseFromParts(parts)).toBeUndefined();
        });
    });
});
//# sourceMappingURL=generateContentResponseUtilities.test.js.map