/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
import { IdeClient, IDEConnectionStatus } from './ide-client.js';
import * as fs from 'node:fs';
import { getIdeProcessInfo } from './process-utils.js';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { detectIde, IDE_DEFINITIONS } from './detect-ide.js';
import * as os from 'node:os';
import * as path from 'node:path';
vi.mock('node:fs', async (importOriginal) => {
    const actual = await importOriginal();
    return {
        ...actual,
        promises: {
            ...actual.promises,
            readFile: vi.fn(),
            readdir: vi.fn(),
        },
        realpathSync: (p) => p,
        existsSync: () => false,
    };
});
vi.mock('./process-utils.js');
vi.mock('@modelcontextprotocol/sdk/client/index.js');
vi.mock('@modelcontextprotocol/sdk/client/streamableHttp.js');
vi.mock('@modelcontextprotocol/sdk/client/stdio.js');
vi.mock('./detect-ide.js');
vi.mock('node:os');
describe('IdeClient', () => {
    let mockClient;
    let mockHttpTransport;
    let mockStdioTransport;
    beforeEach(async () => {
        // Reset singleton instance for test isolation
        IdeClient.instance =
            undefined;
        // Mock environment variables
        process.env['GEMINI_CLI_IDE_WORKSPACE_PATH'] = '/test/workspace';
        delete process.env['GEMINI_CLI_IDE_SERVER_PORT'];
        delete process.env['GEMINI_CLI_IDE_SERVER_STDIO_COMMAND'];
        delete process.env['GEMINI_CLI_IDE_SERVER_STDIO_ARGS'];
        // Mock dependencies
        vi.spyOn(process, 'cwd').mockReturnValue('/test/workspace/sub-dir');
        vi.mocked(detectIde).mockReturnValue(IDE_DEFINITIONS.vscode);
        vi.mocked(getIdeProcessInfo).mockResolvedValue({
            pid: 12345,
            command: 'test-ide',
        });
        vi.mocked(os.tmpdir).mockReturnValue('/tmp');
        // Mock MCP client and transports
        mockClient = {
            connect: vi.fn().mockResolvedValue(undefined),
            close: vi.fn(),
            setNotificationHandler: vi.fn(),
            callTool: vi.fn(),
            request: vi.fn(),
        };
        mockHttpTransport = {
            close: vi.fn(),
        };
        mockStdioTransport = {
            close: vi.fn(),
        };
        vi.mocked(Client).mockReturnValue(mockClient);
        vi.mocked(StreamableHTTPClientTransport).mockReturnValue(mockHttpTransport);
        vi.mocked(StdioClientTransport).mockReturnValue(mockStdioTransport);
        await IdeClient.getInstance();
    });
    afterEach(() => {
        vi.restoreAllMocks();
    });
    describe('connect', () => {
        it('should connect using HTTP when port is provided in config file', async () => {
            const config = { port: '8080' };
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(fs.promises.readFile).toHaveBeenCalledWith(path.join('/tmp/', 'gemini-ide-server-12345.json'), 'utf8');
            expect(StreamableHTTPClientTransport).toHaveBeenCalledWith(new URL('http://127.0.0.1:8080/mcp'), expect.any(Object));
            expect(mockClient.connect).toHaveBeenCalledWith(mockHttpTransport);
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
        });
        it('should connect using stdio when stdio config is provided in file', async () => {
            const config = { stdio: { command: 'test-cmd', args: ['--foo'] } };
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(StdioClientTransport).toHaveBeenCalledWith({
                command: 'test-cmd',
                args: ['--foo'],
            });
            expect(mockClient.connect).toHaveBeenCalledWith(mockStdioTransport);
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
        });
        it('should prioritize port over stdio when both are in config file', async () => {
            const config = {
                port: '8080',
                stdio: { command: 'test-cmd', args: ['--foo'] },
            };
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(StreamableHTTPClientTransport).toHaveBeenCalled();
            expect(StdioClientTransport).not.toHaveBeenCalled();
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
        });
        it('should connect using HTTP when port is provided in environment variables', async () => {
            vi.mocked(fs.promises.readFile).mockRejectedValue(new Error('File not found'));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            process.env['GEMINI_CLI_IDE_SERVER_PORT'] = '9090';
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(StreamableHTTPClientTransport).toHaveBeenCalledWith(new URL('http://127.0.0.1:9090/mcp'), expect.any(Object));
            expect(mockClient.connect).toHaveBeenCalledWith(mockHttpTransport);
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
        });
        it('should connect using stdio when stdio config is in environment variables', async () => {
            vi.mocked(fs.promises.readFile).mockRejectedValue(new Error('File not found'));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            process.env['GEMINI_CLI_IDE_SERVER_STDIO_COMMAND'] = 'env-cmd';
            process.env['GEMINI_CLI_IDE_SERVER_STDIO_ARGS'] = '["--bar"]';
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(StdioClientTransport).toHaveBeenCalledWith({
                command: 'env-cmd',
                args: ['--bar'],
            });
            expect(mockClient.connect).toHaveBeenCalledWith(mockStdioTransport);
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
        });
        it('should prioritize file config over environment variables', async () => {
            const config = { port: '8080' };
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            process.env['GEMINI_CLI_IDE_SERVER_PORT'] = '9090';
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(StreamableHTTPClientTransport).toHaveBeenCalledWith(new URL('http://127.0.0.1:8080/mcp'), expect.any(Object));
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
        });
        it('should be disconnected if no config is found', async () => {
            vi.mocked(fs.promises.readFile).mockRejectedValue(new Error('File not found'));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(StreamableHTTPClientTransport).not.toHaveBeenCalled();
            expect(StdioClientTransport).not.toHaveBeenCalled();
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Disconnected);
            expect(ideClient.getConnectionStatus().details).toContain('Failed to connect');
        });
    });
    describe('getConnectionConfigFromFile', () => {
        it('should return config from the specific pid file if it exists', async () => {
            const config = { port: '1234', workspacePath: '/test/workspace' };
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            const ideClient = await IdeClient.getInstance();
            // In tests, the private method can be accessed like this.
            const result = await ideClient.getConnectionConfigFromFile();
            expect(result).toEqual(config);
            expect(fs.promises.readFile).toHaveBeenCalledWith(path.join('/tmp', 'gemini-ide-server-12345.json'), 'utf8');
        });
        it('should return undefined if no config files are found', async () => {
            vi.mocked(fs.promises.readFile).mockRejectedValue(new Error('not found'));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            const ideClient = await IdeClient.getInstance();
            const result = await ideClient.getConnectionConfigFromFile();
            expect(result).toBeUndefined();
        });
        it('should find and parse a single config file with the new naming scheme', async () => {
            const config = { port: '5678', workspacePath: '/test/workspace' };
            vi.mocked(fs.promises.readFile).mockRejectedValueOnce(new Error('not found')); // For old path
            vi.mocked(fs.promises.readdir).mockResolvedValue(['gemini-ide-server-12345-123.json']);
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
                isValid: true,
            });
            const ideClient = await IdeClient.getInstance();
            const result = await ideClient.getConnectionConfigFromFile();
            expect(result).toEqual(config);
            expect(fs.promises.readFile).toHaveBeenCalledWith(path.join('/tmp/gemini/ide', 'gemini-ide-server-12345-123.json'), 'utf8');
        });
        it('should filter out configs with invalid workspace paths', async () => {
            const validConfig = {
                port: '5678',
                workspacePath: '/test/workspace',
            };
            const invalidConfig = {
                port: '1111',
                workspacePath: '/invalid/workspace',
            };
            vi.mocked(fs.promises.readFile).mockRejectedValueOnce(new Error('not found'));
            vi.mocked(fs.promises.readdir).mockResolvedValue([
                'gemini-ide-server-12345-111.json',
                'gemini-ide-server-12345-222.json',
            ]);
            vi.mocked(fs.promises.readFile)
                .mockResolvedValueOnce(JSON.stringify(invalidConfig))
                .mockResolvedValueOnce(JSON.stringify(validConfig));
            const validateSpy = vi
                .spyOn(IdeClient, 'validateWorkspacePath')
                .mockReturnValueOnce({ isValid: false })
                .mockReturnValueOnce({ isValid: true });
            const ideClient = await IdeClient.getInstance();
            const result = await ideClient.getConnectionConfigFromFile();
            expect(result).toEqual(validConfig);
            expect(validateSpy).toHaveBeenCalledWith('/invalid/workspace', '/test/workspace/sub-dir');
            expect(validateSpy).toHaveBeenCalledWith('/test/workspace', '/test/workspace/sub-dir');
        });
        it('should return the first valid config when multiple workspaces are valid', async () => {
            const config1 = { port: '1111', workspacePath: '/test/workspace' };
            const config2 = { port: '2222', workspacePath: '/test/workspace2' };
            vi.mocked(fs.promises.readFile).mockRejectedValueOnce(new Error('not found'));
            vi.mocked(fs.promises.readdir).mockResolvedValue([
                'gemini-ide-server-12345-111.json',
                'gemini-ide-server-12345-222.json',
            ]);
            vi.mocked(fs.promises.readFile)
                .mockResolvedValueOnce(JSON.stringify(config1))
                .mockResolvedValueOnce(JSON.stringify(config2));
            vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
                isValid: true,
            });
            const ideClient = await IdeClient.getInstance();
            const result = await ideClient.getConnectionConfigFromFile();
            expect(result).toEqual(config1);
        });
        it('should prioritize the config matching the port from the environment variable', async () => {
            process.env['GEMINI_CLI_IDE_SERVER_PORT'] = '2222';
            const config1 = { port: '1111', workspacePath: '/test/workspace' };
            const config2 = { port: '2222', workspacePath: '/test/workspace2' };
            vi.mocked(fs.promises.readFile).mockRejectedValueOnce(new Error('not found'));
            vi.mocked(fs.promises.readdir).mockResolvedValue([
                'gemini-ide-server-12345-111.json',
                'gemini-ide-server-12345-222.json',
            ]);
            vi.mocked(fs.promises.readFile)
                .mockResolvedValueOnce(JSON.stringify(config1))
                .mockResolvedValueOnce(JSON.stringify(config2));
            vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
                isValid: true,
            });
            const ideClient = await IdeClient.getInstance();
            const result = await ideClient.getConnectionConfigFromFile();
            expect(result).toEqual(config2);
        });
        it('should handle invalid JSON in one of the config files', async () => {
            const validConfig = { port: '2222', workspacePath: '/test/workspace' };
            vi.mocked(fs.promises.readFile).mockRejectedValueOnce(new Error('not found'));
            vi.mocked(fs.promises.readdir).mockResolvedValue([
                'gemini-ide-server-12345-111.json',
                'gemini-ide-server-12345-222.json',
            ]);
            vi.mocked(fs.promises.readFile)
                .mockResolvedValueOnce('invalid json')
                .mockResolvedValueOnce(JSON.stringify(validConfig));
            vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
                isValid: true,
            });
            const ideClient = await IdeClient.getInstance();
            const result = await ideClient.getConnectionConfigFromFile();
            expect(result).toEqual(validConfig);
        });
        it('should return undefined if readdir throws an error', async () => {
            vi.mocked(fs.promises.readFile).mockRejectedValueOnce(new Error('not found'));
            vi.mocked(fs.promises.readdir).mockRejectedValue(new Error('readdir failed'));
            const ideClient = await IdeClient.getInstance();
            const result = await ideClient.getConnectionConfigFromFile();
            expect(result).toBeUndefined();
        });
        it('should ignore files with invalid names', async () => {
            const validConfig = { port: '3333', workspacePath: '/test/workspace' };
            vi.mocked(fs.promises.readFile).mockRejectedValueOnce(new Error('not found'));
            vi.mocked(fs.promises.readdir).mockResolvedValue([
                'gemini-ide-server-12345-111.json', // valid
                'not-a-config-file.txt', // invalid
                'gemini-ide-server-asdf.json', // invalid
            ]);
            vi.mocked(fs.promises.readFile).mockResolvedValueOnce(JSON.stringify(validConfig));
            vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
                isValid: true,
            });
            const ideClient = await IdeClient.getInstance();
            const result = await ideClient.getConnectionConfigFromFile();
            expect(result).toEqual(validConfig);
            expect(fs.promises.readFile).toHaveBeenCalledWith(path.join('/tmp/gemini/ide', 'gemini-ide-server-12345-111.json'), 'utf8');
            expect(fs.promises.readFile).not.toHaveBeenCalledWith(path.join('/tmp/gemini/ide', 'not-a-config-file.txt'), 'utf8');
        });
        it('should match env port string to a number port in the config', async () => {
            process.env['GEMINI_CLI_IDE_SERVER_PORT'] = '3333';
            const config1 = { port: 1111, workspacePath: '/test/workspace' };
            const config2 = { port: 3333, workspacePath: '/test/workspace2' };
            vi.mocked(fs.promises.readFile).mockRejectedValueOnce(new Error('not found'));
            vi.mocked(fs.promises.readdir).mockResolvedValue([
                'gemini-ide-server-12345-111.json',
                'gemini-ide-server-12345-222.json',
            ]);
            vi.mocked(fs.promises.readFile)
                .mockResolvedValueOnce(JSON.stringify(config1))
                .mockResolvedValueOnce(JSON.stringify(config2));
            vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
                isValid: true,
            });
            const ideClient = await IdeClient.getInstance();
            const result = await ideClient.getConnectionConfigFromFile();
            expect(result).toEqual(config2);
        });
    });
    describe('isDiffingEnabled', () => {
        it('should return false if not connected', async () => {
            const ideClient = await IdeClient.getInstance();
            expect(ideClient.isDiffingEnabled()).toBe(false);
        });
        it('should return false if tool discovery fails', async () => {
            const config = { port: '8080' };
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            mockClient.request.mockRejectedValue(new Error('Method not found'));
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
            expect(ideClient.isDiffingEnabled()).toBe(false);
        });
        it('should return false if diffing tools are not available', async () => {
            const config = { port: '8080' };
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            mockClient.request.mockResolvedValue({
                tools: [{ name: 'someOtherTool' }],
            });
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
            expect(ideClient.isDiffingEnabled()).toBe(false);
        });
        it('should return false if only openDiff tool is available', async () => {
            const config = { port: '8080' };
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            mockClient.request.mockResolvedValue({
                tools: [{ name: 'openDiff' }],
            });
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
            expect(ideClient.isDiffingEnabled()).toBe(false);
        });
        it('should return true if connected and diffing tools are available', async () => {
            const config = { port: '8080' };
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            mockClient.request.mockResolvedValue({
                tools: [{ name: 'openDiff' }, { name: 'closeDiff' }],
            });
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
            expect(ideClient.isDiffingEnabled()).toBe(true);
        });
    });
    describe('resolveDiffFromCli', () => {
        beforeEach(async () => {
            // Ensure client is "connected" for these tests
            const ideClient = await IdeClient.getInstance();
            // We need to set the client property on the instance for openDiff to work
            ideClient.client = mockClient;
            mockClient.request.mockResolvedValue({
                isError: false,
                content: [],
            });
        });
        it("should resolve an open diff as 'accepted' and return the final content", async () => {
            const ideClient = await IdeClient.getInstance();
            const closeDiffSpy = vi
                .spyOn(ideClient, 'closeDiff')
                .mockResolvedValue('final content from ide');
            const diffPromise = ideClient.openDiff('/test.txt', 'new content');
            // Yield to the event loop to allow the openDiff promise executor to run
            await new Promise((resolve) => setImmediate(resolve));
            await ideClient.resolveDiffFromCli('/test.txt', 'accepted');
            const result = await diffPromise;
            expect(result).toEqual({
                status: 'accepted',
                content: 'final content from ide',
            });
            expect(closeDiffSpy).toHaveBeenCalledWith('/test.txt', {
                suppressNotification: true,
            });
            expect(ideClient.diffResponses.has('/test.txt')).toBe(false);
        });
        it("should resolve an open diff as 'rejected'", async () => {
            const ideClient = await IdeClient.getInstance();
            const closeDiffSpy = vi
                .spyOn(ideClient, 'closeDiff')
                .mockResolvedValue(undefined);
            const diffPromise = ideClient.openDiff('/test.txt', 'new content');
            // Yield to the event loop to allow the openDiff promise executor to run
            await new Promise((resolve) => setImmediate(resolve));
            await ideClient.resolveDiffFromCli('/test.txt', 'rejected');
            const result = await diffPromise;
            expect(result).toEqual({
                status: 'rejected',
                content: undefined,
            });
            expect(closeDiffSpy).toHaveBeenCalledWith('/test.txt', {
                suppressNotification: true,
            });
            expect(ideClient.diffResponses.has('/test.txt')).toBe(false);
        });
        it('should do nothing if no diff is open for the given file path', async () => {
            const ideClient = await IdeClient.getInstance();
            const closeDiffSpy = vi
                .spyOn(ideClient, 'closeDiff')
                .mockResolvedValue(undefined);
            // No call to openDiff, so no resolver will exist.
            await ideClient.resolveDiffFromCli('/non-existent.txt', 'accepted');
            expect(closeDiffSpy).toHaveBeenCalledWith('/non-existent.txt', {
                suppressNotification: true,
            });
            // No crash should occur, and nothing should be in the map.
            expect(ideClient.diffResponses.has('/non-existent.txt')).toBe(false);
        });
    });
    describe('closeDiff', () => {
        beforeEach(async () => {
            const ideClient = await IdeClient.getInstance();
            ideClient.client = mockClient;
        });
        it('should return undefined if client is not connected', async () => {
            const ideClient = await IdeClient.getInstance();
            ideClient.client =
                undefined;
            const result = await ideClient.closeDiff('/test.txt');
            expect(result).toBeUndefined();
        });
        it('should call client.request with correct arguments', async () => {
            const ideClient = await IdeClient.getInstance();
            // Return a valid, empty response as the return value is not under test here.
            mockClient.request.mockResolvedValue({ isError: false, content: [] });
            await ideClient.closeDiff('/test.txt', { suppressNotification: true });
            expect(mockClient.request).toHaveBeenCalledWith(expect.objectContaining({
                params: {
                    name: 'closeDiff',
                    arguments: {
                        filePath: '/test.txt',
                        suppressNotification: true,
                    },
                },
            }), expect.any(Object), // Schema
            expect.any(Object));
        });
        it('should return content from a valid JSON response', async () => {
            const ideClient = await IdeClient.getInstance();
            const response = {
                isError: false,
                content: [
                    { type: 'text', text: JSON.stringify({ content: 'file content' }) },
                ],
            };
            mockClient.request.mockResolvedValue(response);
            const result = await ideClient.closeDiff('/test.txt');
            expect(result).toBe('file content');
        });
        it('should return undefined for a valid JSON response with null content', async () => {
            const ideClient = await IdeClient.getInstance();
            const response = {
                isError: false,
                content: [{ type: 'text', text: JSON.stringify({ content: null }) }],
            };
            mockClient.request.mockResolvedValue(response);
            const result = await ideClient.closeDiff('/test.txt');
            expect(result).toBeUndefined();
        });
        it('should return undefined if response is not valid JSON', async () => {
            const ideClient = await IdeClient.getInstance();
            const response = {
                isError: false,
                content: [{ type: 'text', text: 'not json' }],
            };
            mockClient.request.mockResolvedValue(response);
            const result = await ideClient.closeDiff('/test.txt');
            expect(result).toBeUndefined();
        });
        it('should return undefined if request result has isError: true', async () => {
            const ideClient = await IdeClient.getInstance();
            const response = {
                isError: true,
                content: [{ type: 'text', text: 'An error occurred' }],
            };
            mockClient.request.mockResolvedValue(response);
            const result = await ideClient.closeDiff('/test.txt');
            expect(result).toBeUndefined();
        });
        it('should return undefined if client.request throws', async () => {
            const ideClient = await IdeClient.getInstance();
            mockClient.request.mockRejectedValue(new Error('Request failed'));
            const result = await ideClient.closeDiff('/test.txt');
            expect(result).toBeUndefined();
        });
        it('should return undefined if response has no text part', async () => {
            const ideClient = await IdeClient.getInstance();
            const response = {
                isError: false,
                content: [{ type: 'other' }],
            };
            mockClient.request.mockResolvedValue(response);
            const result = await ideClient.closeDiff('/test.txt');
            expect(result).toBeUndefined();
        });
        it('should return undefined if response is falsy', async () => {
            const ideClient = await IdeClient.getInstance();
            // Mocking with `null as any` to test the falsy path, as the mock
            // function is strictly typed.
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            mockClient.request.mockResolvedValue(null);
            const result = await ideClient.closeDiff('/test.txt');
            expect(result).toBeUndefined();
        });
    });
    describe('authentication', () => {
        it('should connect with an auth token if provided in the discovery file', async () => {
            const authToken = 'test-auth-token';
            const config = { port: '8080', authToken };
            vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
            vi.mocked(fs.promises.readdir).mockResolvedValue([]);
            const ideClient = await IdeClient.getInstance();
            await ideClient.connect();
            expect(StreamableHTTPClientTransport).toHaveBeenCalledWith(new URL('http://127.0.0.1:8080/mcp'), expect.objectContaining({
                requestInit: {
                    headers: {
                        Authorization: `Bearer ${authToken}`,
                    },
                },
            }));
            expect(ideClient.getConnectionStatus().status).toBe(IDEConnectionStatus.Connected);
        });
    });
});
//# sourceMappingURL=ide-client.test.js.map