import { describe, it, expect, vi, beforeAll, beforeEach } from 'vitest';
import { execFile } from 'child_process';
import { readFile, unlink } from 'fs/promises';
import type { ChildProcess } from 'child_process';

vi.mock('child_process', () => ({
  execFile: vi.fn(),
}));

vi.mock('fs/promises', () => ({
  readFile: vi.fn(),
  unlink: vi.fn(),
}));

const mockExecFile = vi.mocked(execFile);
const mockReadFile = vi.mocked(readFile);
const mockUnlink = vi.mocked(unlink);
type ExecFileCallback = NonNullable<Parameters<typeof execFile>[3]>;

function mockChildProcess(): ChildProcess {
  return {} as ChildProcess;
}

function mockExecFileOnce(impl: (callback: ExecFileCallback) => void): void {
  mockExecFile.mockImplementationOnce((_cmd, _args, _opts, callback) => {
    if (typeof callback === 'function') {
      impl(callback as ExecFileCallback);
    }
    return mockChildProcess();
  });
}

describe('capture tools', () => {
  let screenCaptureTool: typeof import('./capture.js').screenCaptureTool;
  let cameraCaptureTool: typeof import('./capture.js').cameraCaptureTool;

  beforeAll(async () => {
    const mod = await import('./capture.js');
    screenCaptureTool = mod.screenCaptureTool;
    cameraCaptureTool = mod.cameraCaptureTool;
  });

  beforeEach(() => {
    vi.clearAllMocks();
    mockReadFile.mockResolvedValue(Buffer.from('image-bytes'));
    mockUnlink.mockResolvedValue(undefined);
  });

  it('screen.capture returns base64 payload when command succeeds', async () => {
    const platformSpy = vi.spyOn(process, 'platform', 'get').mockReturnValue('linux');
    mockExecFileOnce((callback) => callback(null, '', ''));

    const result = await screenCaptureTool.execute({ format: 'png' });
    expect(result.success).toBe(true);
    expect(result.output).toContain('"mimeType":"image/png"');
    expect(mockExecFile).toHaveBeenCalled();

    platformSpy.mockRestore();
  });

  it('camera.capture returns error on unsupported platform', async () => {
    const platformSpy = vi.spyOn(process, 'platform', 'get').mockReturnValue('win32');
    const result = await cameraCaptureTool.execute({});
    expect(result.success).toBe(false);
    expect(result.error).toContain('only supported');
    platformSpy.mockRestore();
  });
});
