import { describe, it, expect, vi } from 'vitest';
import { AddRepositoriesToConfigUseCase, } from '../../../../modules/cli-configuration/usecases/cli/addRepositoriesToConfig.usecase.js';
function createFakeDeps(overrides) {
    return {
        readFileSync: vi.fn(() => JSON.stringify({
            server: { port: 3847 },
            user: { gitlabUsername: '', githubUsername: '' },
            queue: { maxConcurrent: 2, deduplicationWindowMs: 300000 },
            repositories: [],
        })),
        writeFileSync: vi.fn(),
        existsSync: vi.fn(() => true),
        ...overrides,
    };
}
describe('AddRepositoriesToConfigUseCase', () => {
    it('should add a new repository to an existing config', () => {
        const deps = createFakeDeps();
        const usecase = new AddRepositoriesToConfigUseCase(deps);
        const result = usecase.execute({
            configPath: '/home/user/.config/reviewflow/config.json',
            newRepositories: [
                { name: 'my-app', localPath: '/home/user/projects/my-app', enabled: true },
            ],
        });
        expect(result.added).toHaveLength(1);
        expect(result.added[0].name).toBe('my-app');
        expect(result.skipped).toHaveLength(0);
    });
    it('should skip repositories already present in config', () => {
        const deps = createFakeDeps({
            readFileSync: vi.fn(() => JSON.stringify({
                server: { port: 3847 },
                user: { gitlabUsername: '', githubUsername: '' },
                queue: { maxConcurrent: 2, deduplicationWindowMs: 300000 },
                repositories: [
                    { name: 'existing-app', localPath: '/home/user/projects/existing-app', enabled: true },
                ],
            })),
        });
        const usecase = new AddRepositoriesToConfigUseCase(deps);
        const result = usecase.execute({
            configPath: '/config/config.json',
            newRepositories: [
                { name: 'existing-app', localPath: '/home/user/projects/existing-app', enabled: true },
            ],
        });
        expect(result.added).toHaveLength(0);
        expect(result.skipped).toHaveLength(1);
        expect(result.skipped[0].name).toBe('existing-app');
    });
    it('should handle a mix of new and existing repositories', () => {
        const deps = createFakeDeps({
            readFileSync: vi.fn(() => JSON.stringify({
                server: { port: 3847 },
                user: { gitlabUsername: '', githubUsername: '' },
                queue: { maxConcurrent: 2, deduplicationWindowMs: 300000 },
                repositories: [
                    { name: 'old-app', localPath: '/projects/old-app', enabled: true },
                ],
            })),
        });
        const usecase = new AddRepositoriesToConfigUseCase(deps);
        const result = usecase.execute({
            configPath: '/config/config.json',
            newRepositories: [
                { name: 'old-app', localPath: '/projects/old-app', enabled: true },
                { name: 'new-app', localPath: '/projects/new-app', enabled: true },
            ],
        });
        expect(result.added).toHaveLength(1);
        expect(result.added[0].name).toBe('new-app');
        expect(result.skipped).toHaveLength(1);
        expect(result.skipped[0].name).toBe('old-app');
    });
    it('should throw when config file does not exist', () => {
        const deps = createFakeDeps({
            existsSync: vi.fn(() => false),
        });
        const usecase = new AddRepositoriesToConfigUseCase(deps);
        expect(() => usecase.execute({
            configPath: '/missing/config.json',
            newRepositories: [
                { name: 'app', localPath: '/projects/app', enabled: true },
            ],
        })).toThrow();
    });
    it('should throw a meaningful error when config contains invalid JSON', () => {
        const deps = createFakeDeps({
            readFileSync: vi.fn(() => '{ invalid json !!!'),
        });
        const usecase = new AddRepositoriesToConfigUseCase(deps);
        expect(() => usecase.execute({
            configPath: '/config/config.json',
            newRepositories: [
                { name: 'app', localPath: '/projects/app', enabled: true },
            ],
        })).toThrow('Invalid JSON in configuration file: /config/config.json');
    });
    it('should write the merged repositories back to config file', () => {
        const existingConfig = {
            server: { port: 3847 },
            user: { gitlabUsername: 'me', githubUsername: '' },
            queue: { maxConcurrent: 2, deduplicationWindowMs: 300000 },
            repositories: [
                { name: 'old-app', localPath: '/projects/old-app', enabled: true },
            ],
        };
        const writeFileSync = vi.fn();
        const deps = createFakeDeps({
            readFileSync: vi.fn(() => JSON.stringify(existingConfig)),
            writeFileSync,
        });
        const usecase = new AddRepositoriesToConfigUseCase(deps);
        usecase.execute({
            configPath: '/config/config.json',
            newRepositories: [
                { name: 'new-app', localPath: '/projects/new-app', enabled: true },
            ],
        });
        const writtenConfig = JSON.parse(writeFileSync.mock.calls[0][1]);
        expect(writtenConfig.repositories).toHaveLength(2);
        expect(writtenConfig.server.port).toBe(3847);
        expect(writtenConfig.user.gitlabUsername).toBe('me');
    });
});
//# sourceMappingURL=addRepositoriesToConfig.usecase.test.js.map