import { describe, it, expect, beforeEach } from 'vitest';
import { sweepStaleWorktrees } from '../../../../../modules/worktree-management/usecases/sweepStaleWorktrees.usecase.js';
import { deriveWorktreePath } from '../../../../../modules/worktree-management/entities/worktree/worktree.js';
function buildTrackedMr(overrides) {
    return {
        id: overrides.id ?? 'gitlab-group-project-1',
        mrNumber: overrides.mrNumber ?? 1,
        title: 'title',
        url: 'http://example.com',
        project: overrides.project ?? 'group/project',
        platform: overrides.platform ?? 'gitlab',
        sourceBranch: 'feat/x',
        targetBranch: 'master',
        assignment: {
            username: 'user',
            assignedAt: '2026-05-01T00:00:00Z',
        },
        state: overrides.state ?? 'pending-review',
        openThreads: 0,
        totalThreads: 0,
        createdAt: '2026-05-01T00:00:00Z',
        lastReviewAt: null,
        lastPushAt: null,
        approvedAt: null,
        mergedAt: overrides.mergedAt ?? null,
        reviews: [],
        totalReviews: 0,
        totalFollowups: 0,
        totalBlocking: 0,
        totalWarnings: 0,
        totalSuggestions: 0,
        totalDurationMs: 0,
        latestScore: null,
        autoFollowup: true,
        bypass: null,
    };
}
function buildEntry(identity, mtime) {
    return {
        identity,
        path: deriveWorktreePath(identity),
        mtime,
    };
}
describe('sweepStaleWorktrees use case', () => {
    let removed;
    let fakeTracking;
    beforeEach(() => {
        removed = [];
        fakeTracking = {
            trackedMrs: new Map(),
            getById(projectPath, mrId) {
                const stored = this.trackedMrs.get(`${projectPath}::${mrId}`) ?? null;
                return stored;
            },
        };
    });
    const repository = { localPath: '/repos/group-project', enabled: true };
    const now = new Date('2026-05-23T12:00:00Z');
    function trackingFor(identity, tracked) {
        const mrId = `${identity.platform}-${identity.projectPath}-${identity.mrNumber}`;
        fakeTracking.trackedMrs.set(`${repository.localPath}::${mrId}`, tracked);
    }
    async function runSweep(entries) {
        await sweepStaleWorktrees({
            listEntries: async () => entries,
            removeWorktree: async (identity) => {
                removed.push(identity);
                return { status: 'removed' };
            },
            trackingGateway: {
                getById: (projectPath, mrId) => fakeTracking.getById(projectPath, mrId),
            },
            getRepositories: () => [repository],
            now: () => now,
        });
    }
    it('removes worktree when matching MR is merged more than 24h ago', async () => {
        const identity = { platform: 'gitlab', projectPath: 'group-project', mrNumber: 1 };
        const entry = buildEntry(identity, new Date('2026-05-21T00:00:00Z'));
        trackingFor(identity, buildTrackedMr({
            id: 'gitlab-group-project-1',
            state: 'merged',
            mergedAt: '2026-05-21T00:00:00Z',
        }));
        await runSweep([entry]);
        expect(removed).toEqual([identity]);
    });
    it('keeps worktree when MR was merged less than 24h ago', async () => {
        const identity = { platform: 'gitlab', projectPath: 'group-project', mrNumber: 2 };
        const entry = buildEntry(identity, new Date('2026-05-23T00:00:00Z'));
        trackingFor(identity, buildTrackedMr({
            id: 'gitlab-group-project-2',
            mrNumber: 2,
            state: 'merged',
            mergedAt: '2026-05-23T06:00:00Z',
        }));
        await runSweep([entry]);
        expect(removed).toEqual([]);
    });
    it('removes orphan worktree when no tracked MR exists', async () => {
        const identity = { platform: 'gitlab', projectPath: 'group-project', mrNumber: 3 };
        const entry = buildEntry(identity, new Date('2026-05-23T11:00:00Z'));
        await runSweep([entry]);
        expect(removed).toEqual([identity]);
    });
    it('removes stale worktree with mtime older than 7 days regardless of MR state', async () => {
        const identity = { platform: 'gitlab', projectPath: 'group-project', mrNumber: 4 };
        const eightDaysAgo = new Date(now.getTime() - 8 * 24 * 60 * 60 * 1000);
        const entry = buildEntry(identity, eightDaysAgo);
        trackingFor(identity, buildTrackedMr({
            id: 'gitlab-group-project-4',
            mrNumber: 4,
            state: 'pending-review',
        }));
        await runSweep([entry]);
        expect(removed).toEqual([identity]);
    });
    it('keeps active worktree with fresh mtime', async () => {
        const identity = { platform: 'gitlab', projectPath: 'group-project', mrNumber: 5 };
        const sixDaysAgo = new Date(now.getTime() - 6 * 24 * 60 * 60 * 1000);
        const entry = buildEntry(identity, sixDaysAgo);
        trackingFor(identity, buildTrackedMr({
            id: 'gitlab-group-project-5',
            mrNumber: 5,
            state: 'pending-review',
        }));
        await runSweep([entry]);
        expect(removed).toEqual([]);
    });
});
//# sourceMappingURL=sweepStaleWorktrees.usecase.test.js.map