"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const cache_1 = require("../../src/cache");
const logger_1 = __importDefault(require("../../src/logger"));
const vertex_1 = require("../../src/providers/vertex");
const vertexUtil = __importStar(require("../../src/providers/vertexUtil"));
jest.mock('../../src/cache', () => ({
    getCache: jest.fn().mockReturnValue({
        get: jest.fn(),
        set: jest.fn(),
    }),
    isCacheEnabled: jest.fn(),
}));
jest.mock('../../src/providers/vertexUtil', () => ({
    ...jest.requireActual('../../src/providers/vertexUtil'),
    getGoogleClient: jest.fn(),
}));
jest.mock('../../src/logger');
describe('VertexChatProvider.callGeminiApi', () => {
    let provider;
    beforeEach(() => {
        provider = new vertex_1.VertexChatProvider('gemini-pro', {
            config: {
                context: 'test-context',
                examples: [{ input: 'example input', output: 'example output' }],
                stopSequence: ['\n'],
                temperature: 0.7,
                maxOutputTokens: 100,
                topP: 0.9,
                topK: 40,
            },
        });
        jest.mocked(cache_1.getCache).mockReturnValue({
            get: jest.fn(),
            set: jest.fn(),
            wrap: jest.fn(),
            del: jest.fn(),
            reset: jest.fn(),
            store: {},
        });
        jest.mocked(cache_1.isCacheEnabled).mockReturnValue(true);
    });
    afterEach(() => {
        jest.clearAllMocks();
    });
    it('should call the Gemini API and return the response', async () => {
        const mockResponse = {
            data: [
                {
                    candidates: [{ content: { parts: [{ text: 'response text' }] } }],
                    usageMetadata: {
                        totalTokenCount: 10,
                        promptTokenCount: 5,
                        candidatesTokenCount: 5,
                    },
                },
            ],
        };
        const mockRequest = jest.fn().mockResolvedValue(mockResponse);
        jest.spyOn(vertexUtil, 'getGoogleClient').mockResolvedValue({
            client: {
                request: mockRequest,
            },
            projectId: 'test-project-id',
        });
        const response = await provider.callGeminiApi('test prompt');
        expect(response).toEqual({
            cached: false,
            output: 'response text',
            tokenUsage: {
                total: 10,
                prompt: 5,
                completion: 5,
            },
        });
        expect(vertexUtil.getGoogleClient).toHaveBeenCalledWith();
        expect(mockRequest).toHaveBeenCalledWith({
            url: expect.any(String),
            method: 'POST',
            data: expect.objectContaining({
                contents: [{ parts: { text: 'test prompt' }, role: 'user' }],
            }),
            timeout: expect.any(Number),
        });
    });
    it('should return cached response if available', async () => {
        const mockCachedResponse = {
            cached: true,
            output: 'cached response text',
            tokenUsage: {
                total: 10,
                prompt: 5,
                completion: 5,
            },
        };
        jest.mocked((0, cache_1.getCache)().get).mockResolvedValue(JSON.stringify(mockCachedResponse));
        const response = await provider.callGeminiApi('test prompt');
        expect(response).toEqual({
            ...mockCachedResponse,
            tokenUsage: {
                ...mockCachedResponse.tokenUsage,
                cached: mockCachedResponse.tokenUsage.total,
            },
        });
    });
    it('should handle API call errors', async () => {
        const mockError = new Error('something went wrong');
        jest.spyOn(vertexUtil, 'getGoogleClient').mockResolvedValue({
            client: {
                request: jest.fn().mockRejectedValue(mockError),
            },
            projectId: 'test-project-id',
        });
        const response = await provider.callGeminiApi('test prompt');
        expect(response).toEqual({
            error: `API call error: Error: something went wrong`,
        });
    });
    it('should handle API response errors', async () => {
        const mockResponse = {
            data: [
                {
                    error: {
                        code: 400,
                        message: 'Bad Request',
                    },
                },
            ],
        };
        jest.spyOn(vertexUtil, 'getGoogleClient').mockResolvedValue({
            client: {
                request: jest.fn().mockResolvedValue(mockResponse),
            },
            projectId: 'test-project-id',
        });
        const response = await provider.callGeminiApi('test prompt');
        expect(response).toEqual({
            error: 'Error 400: Bad Request',
        });
    });
});
describe('maybeCoerceToGeminiFormat', () => {
    it('should return unmodified content if it matches GeminiFormat', () => {
        const input = [
            {
                role: 'user',
                parts: [{ text: 'Hello, Gemini!' }],
            },
        ];
        const result = vertexUtil.maybeCoerceToGeminiFormat(input);
        expect(result).toEqual({
            contents: input,
            coerced: false,
            systemInstruction: undefined,
        });
    });
    it('should coerce OpenAI chat format to GeminiFormat', () => {
        const input = [
            { role: 'user', content: 'Hello' },
            { role: 'user', content: ', ' },
            { role: 'user', content: 'Gemini!' },
        ];
        const expected = [
            {
                role: 'user',
                parts: [{ text: 'Hello' }],
            },
            {
                role: 'user',
                parts: [{ text: ', ' }],
            },
            {
                role: 'user',
                parts: [{ text: 'Gemini!' }],
            },
        ];
        const result = vertexUtil.maybeCoerceToGeminiFormat(input);
        expect(result).toEqual({
            contents: expected,
            coerced: true,
            systemInstruction: undefined,
        });
    });
    it('should coerce string input to GeminiFormat', () => {
        const input = 'Hello, Gemini!';
        const expected = [
            {
                parts: [{ text: 'Hello, Gemini!' }],
            },
        ];
        const result = vertexUtil.maybeCoerceToGeminiFormat(input);
        expect(result).toEqual({
            contents: expected,
            coerced: true,
            systemInstruction: undefined,
        });
    });
    it('should handle system messages and create systemInstruction', () => {
        const input = [
            { role: 'system', content: 'You are a helpful assistant.' },
            { role: 'user', content: 'Hello!' },
        ];
        const result = vertexUtil.maybeCoerceToGeminiFormat(input);
        expect(result).toEqual({
            contents: [
                {
                    role: 'user',
                    parts: [{ text: 'Hello!' }],
                },
            ],
            coerced: true,
            systemInstruction: {
                parts: [{ text: 'You are a helpful assistant.' }],
            },
        });
    });
    it('should log a warning and return the input for unknown formats', () => {
        const loggerSpy = jest.spyOn(logger_1.default, 'warn');
        const input = { unknownFormat: 'test' };
        const result = vertexUtil.maybeCoerceToGeminiFormat(input);
        expect(result).toEqual({
            contents: input,
            coerced: false,
            systemInstruction: undefined,
        });
        expect(loggerSpy).toHaveBeenCalledWith(`Unknown format for Gemini: ${JSON.stringify(input)}`);
    });
});
//# sourceMappingURL=vertex.test.js.map