/**
 * @license
 * Copyright 2026 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
import { SandboxedFileSystemService } from './sandboxedFileSystemService.js';
import { spawn } from 'node:child_process';
import { EventEmitter } from 'node:events';
vi.mock('node:child_process', () => ({
    spawn: vi.fn(),
}));
class MockSandboxManager {
    async prepareCommand(req) {
        return {
            program: 'sandbox.exe',
            args: ['0', req.cwd, req.command, ...req.args],
            env: req.env || {},
        };
    }
}
describe('SandboxedFileSystemService', () => {
    let sandboxManager;
    let service;
    const cwd = '/test/cwd';
    beforeEach(() => {
        sandboxManager = new MockSandboxManager();
        service = new SandboxedFileSystemService(sandboxManager, cwd);
        vi.clearAllMocks();
    });
    afterEach(() => {
        vi.restoreAllMocks();
    });
    it('should read a file through the sandbox', async () => {
        const mockChild = new EventEmitter();
        Object.assign(mockChild, {
            stdout: new EventEmitter(),
            stderr: new EventEmitter(),
        });
        vi.mocked(spawn).mockReturnValue(mockChild);
        const readPromise = service.readTextFile('/test/file.txt');
        // Use setImmediate to ensure events are emitted after the promise starts executing
        setImmediate(() => {
            mockChild.stdout.emit('data', Buffer.from('file content'));
            mockChild.emit('close', 0);
        });
        const content = await readPromise;
        expect(content).toBe('file content');
        expect(spawn).toHaveBeenCalledWith('sandbox.exe', ['0', cwd, '__read', '/test/file.txt'], expect.any(Object));
    });
    it('should write a file through the sandbox', async () => {
        const mockChild = new EventEmitter();
        const mockStdin = new EventEmitter();
        Object.assign(mockStdin, {
            write: vi.fn(),
            end: vi.fn(),
        });
        Object.assign(mockChild, {
            stdin: mockStdin,
            stderr: new EventEmitter(),
        });
        vi.mocked(spawn).mockReturnValue(mockChild);
        const writePromise = service.writeTextFile('/test/file.txt', 'new content');
        setImmediate(() => {
            mockChild.emit('close', 0);
        });
        await writePromise;
        expect(mockStdin.write).toHaveBeenCalledWith('new content');
        expect(mockStdin.end).toHaveBeenCalled();
        expect(spawn).toHaveBeenCalledWith('sandbox.exe', ['0', cwd, '__write', '/test/file.txt'], expect.any(Object));
    });
    it('should reject if sandbox command fails', async () => {
        const mockChild = new EventEmitter();
        Object.assign(mockChild, {
            stdout: new EventEmitter(),
            stderr: new EventEmitter(),
        });
        vi.mocked(spawn).mockReturnValue(mockChild);
        const readPromise = service.readTextFile('/test/file.txt');
        setImmediate(() => {
            mockChild.stderr.emit('data', Buffer.from('access denied'));
            mockChild.emit('close', 1);
        });
        await expect(readPromise).rejects.toThrow("Sandbox Error: read_file failed for '/test/file.txt'. Exit code 1. Details: access denied");
    });
});
//# sourceMappingURL=sandboxedFileSystemService.test.js.map