import {
  enforceRunRetention,
  getRunRetentionConfig,
  isTerminalRunForRetention,
  sortRunsOldestFirst,
} from '../runs/run-retention.js';
import { MemoryRunStore } from '../runs/memoryRunStore.js';

jest.mock('../runs/index.js', () => ({
  getRunStore: jest.fn(),
}));

jest.mock('../config/persistence.js', () => ({
  getPersistenceMode: jest.fn(() => 'memory'),
}));

jest.mock('../db/prisma.js', () => ({
  getPrismaClient: jest.fn(),
}));

import { getRunStore } from '../runs/index.js';

describe('run-retention', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('getRunRetentionConfig defaults', () => {
    delete process.env.RUN_RETENTION_ENABLED;
    delete process.env.RUN_RETENTION_MAX_COUNT;
    delete process.env.RUN_RETENTION_MAX_AGE_DAYS;
    const c = getRunRetentionConfig();
    expect(c.enabled).toBe(true);
    expect(c.maxCount).toBe(100);
    expect(c.maxAgeDays).toBe(0);
  });

  it('isTerminalRunForRetention', () => {
    expect(isTerminalRunForRetention('completed')).toBe(true);
    expect(isTerminalRunForRetention('failed')).toBe(true);
    expect(isTerminalRunForRetention('killed')).toBe(true);
    expect(isTerminalRunForRetention('running')).toBe(false);
    expect(isTerminalRunForRetention('queued')).toBe(false);
  });

  it('deletes oldest terminal runs when over maxCount', async () => {
    const store = new MemoryRunStore();
    (getRunStore as jest.Mock).mockReturnValue(store);

    for (let i = 0; i < 5; i++) {
      const run = await store.createRun({ name: `run-${i}` });
      await store.updateRunStatus(run.id, i < 3 ? 'completed' : 'running');
      // Stagger createdAt via direct map hack — memory store sets createdAt at create
    }

    const result = await enforceRunRetention({
      enabled: true,
      maxCount: 3,
      maxAgeDays: 0,
    });

    expect(result.deletedByCount).toBeGreaterThanOrEqual(1);
    const left = await store.listRuns();
    expect(left.length).toBeLessThanOrEqual(3);
    expect(left.some((r) => r.status === 'running')).toBe(true);
  });

  it('sortRunsOldestFirst orders by createdAt', () => {
    const sorted = sortRunsOldestFirst([
      {
        id: '2',
        name: 'b',
        status: 'completed',
        createdAt: '2026-01-02T00:00:00.000Z',
        updatedAt: '2026-01-02T00:00:00.000Z',
        logs: [],
        tags: [],
        startedAt: null,
        completedAt: null,
      },
      {
        id: '1',
        name: 'a',
        status: 'completed',
        createdAt: '2026-01-01T00:00:00.000Z',
        updatedAt: '2026-01-01T00:00:00.000Z',
        logs: [],
        tags: [],
        startedAt: null,
        completedAt: null,
      },
    ]);
    expect(sorted[0].id).toBe('1');
  });
});
