import { describe, it, expect, vi, beforeEach } from 'vitest';
import { writeMcpContext, cleanupMcpContext } from '../../../../frameworks/claude/claudeInvoker.js';
import { ReviewJobFactory } from '../../../factories/reviewJob.factory.js';
import * as fs from 'node:fs';
import * as os from 'node:os';
vi.mock('node:fs');
vi.mock('node:os', () => ({
    homedir: vi.fn(() => '/home/testuser'),
}));
describe('MCP Context file management', () => {
    beforeEach(() => {
        vi.resetAllMocks();
        vi.mocked(os.homedir).mockReturnValue('/home/testuser');
        vi.mocked(fs.existsSync).mockReturnValue(false);
    });
    describe('writeMcpContext', () => {
        it('should write per-job context file with correct content', () => {
            const job = ReviewJobFactory.create({ id: 'job-123' });
            writeMcpContext(job);
            expect(fs.mkdirSync).toHaveBeenCalledWith('/home/testuser/.claude-review/jobs', { recursive: true });
            expect(fs.writeFileSync).toHaveBeenCalledWith('/home/testuser/.claude-review/jobs/job-123.json', expect.stringContaining('"jobId": "job-123"'));
        });
        it('should sanitize job ID with special characters in file path', () => {
            const job = ReviewJobFactory.create({ id: 'gitlab:org/repo:mr-5' });
            writeMcpContext(job);
            expect(fs.writeFileSync).toHaveBeenCalledWith('/home/testuser/.claude-review/jobs/gitlab-org-repo-mr-5.json', expect.any(String));
        });
        it('should include mergeRequestId, jobType, and localPath in context', () => {
            const job = ReviewJobFactory.create({
                id: 'job-456',
                platform: 'gitlab',
                projectPath: 'my-org/my-repo',
                mrNumber: 10,
                localPath: '/tmp/repos/my-repo',
                jobType: 'followup',
            });
            writeMcpContext(job);
            const written = vi.mocked(fs.writeFileSync).mock.calls[0][1];
            const parsed = JSON.parse(written);
            expect(parsed.jobId).toBe('job-456');
            expect(parsed.localPath).toBe('/tmp/repos/my-repo');
            expect(parsed.mergeRequestId).toBe('gitlab-my-org/my-repo-10');
            expect(parsed.jobType).toBe('followup');
            expect(parsed.timestamp).toBeDefined();
        });
        it('should write two separate files for concurrent jobs', () => {
            const jobA = ReviewJobFactory.create({ id: 'job-a' });
            const jobB = ReviewJobFactory.createFollowup({ id: 'job-b' });
            writeMcpContext(jobA);
            writeMcpContext(jobB);
            const calls = vi.mocked(fs.writeFileSync).mock.calls;
            const paths = calls.map(([path]) => path);
            expect(paths).toContain('/home/testuser/.claude-review/jobs/job-a.json');
            expect(paths).toContain('/home/testuser/.claude-review/jobs/job-b.json');
        });
        it('should not throw on write failure', () => {
            vi.mocked(fs.mkdirSync).mockImplementation(() => {
                throw new Error('disk full');
            });
            const job = ReviewJobFactory.create();
            expect(() => writeMcpContext(job)).not.toThrow();
        });
    });
    describe('cleanupMcpContext', () => {
        it('should delete the per-job file', () => {
            vi.mocked(fs.existsSync).mockReturnValue(true);
            cleanupMcpContext('job-123');
            expect(fs.unlinkSync).toHaveBeenCalledWith('/home/testuser/.claude-review/jobs/job-123.json');
        });
        it('should not attempt deletion if file does not exist', () => {
            vi.mocked(fs.existsSync).mockReturnValue(false);
            cleanupMcpContext('job-123');
            expect(fs.unlinkSync).not.toHaveBeenCalled();
        });
        it('should only remove the specified job file', () => {
            vi.mocked(fs.existsSync).mockReturnValue(true);
            cleanupMcpContext('job-a');
            expect(fs.unlinkSync).toHaveBeenCalledTimes(1);
            expect(fs.unlinkSync).toHaveBeenCalledWith('/home/testuser/.claude-review/jobs/job-a.json');
        });
        it('should not throw on cleanup failure', () => {
            vi.mocked(fs.existsSync).mockReturnValue(true);
            vi.mocked(fs.unlinkSync).mockImplementation(() => {
                throw new Error('permission denied');
            });
            expect(() => cleanupMcpContext('job-123')).not.toThrow();
        });
    });
});
//# sourceMappingURL=mcpContext.test.js.map