import { describe, it, expect, jest, afterEach } from '@jest/globals';
import { resetPolicyViolationPublisher } from '@4runr/sentinel';
import { executeWithSentinelWatch, SENTINEL_KILL_CHECK_INTERVAL_MS } from '../queue/sentinel-execute-watch.js';
import { formatSentinelKillError } from '../security/sentinel-run-failure.js';

describe('executeWithSentinelWatch', () => {
  afterEach(() => {
    resetPolicyViolationPublisher();
  });

  it('uses 250ms poll interval during execute', () => {
    expect(SENTINEL_KILL_CHECK_INTERVAL_MS).toBe(250);
  });

  it('rejects when Sentinel marks run killed during execute', async () => {
    let calls = 0;
    const getRunStatus = jest.fn(() => {
      calls += 1;
      if (calls >= 2) {
        return { status: 'killed', killReason: 'policy_violation:timeout' };
      }
      return { status: 'running' };
    });

    await expect(
      executeWithSentinelWatch(
        'run-1',
        () => new Promise((resolve) => setTimeout(() => resolve('done'), 2500)),
        getRunStatus
      )
    ).rejects.toThrow(formatSentinelKillError('policy_violation:timeout'));
  });

  it('returns execute result when run stays running', async () => {
    const getRunStatus = jest.fn(() => ({ status: 'running' }));

    const result = await executeWithSentinelWatch(
      'run-2',
      async () => 'ok',
      getRunStatus
    );

    expect(result).toBe('ok');
  });
});
