import {
  SYNTHETIC_JOB_DEFINITION,
  isSyntheticEnabled,
  assertNotProduction,
} from './synthetic-job-definition';
import { JobDefinitionRegistry, DuplicateJobTypeError } from './job-definition-registry';
import { ALLOWED_QUEUE_NAMES } from './job-definition.types';

describe('Synthetic Job Definition', () => {
  const OLD_ENV = { ...process.env };

  afterEach(() => {
    process.env = { ...OLD_ENV };
  });

  describe('环境门控', () => {
    it('NODE_ENV=test + AI_JOB_SYNTHETIC_ENABLED=true → isSyntheticEnabled=true', () => {
      process.env.NODE_ENV = 'test';
      process.env.AI_JOB_SYNTHETIC_ENABLED = 'true';
      expect(isSyntheticEnabled()).toBe(true);
    });

    it('NODE_ENV=production → isSyntheticEnabled=false', () => {
      process.env.NODE_ENV = 'production';
      process.env.AI_JOB_SYNTHETIC_ENABLED = 'true';
      expect(isSyntheticEnabled()).toBe(false);
    });

    it('AI_JOB_SYNTHETIC_ENABLED 未设置 → isSyntheticEnabled=false', () => {
      process.env.NODE_ENV = 'test';
      delete process.env.AI_JOB_SYNTHETIC_ENABLED;
      expect(isSyntheticEnabled()).toBe(false);
    });

    it('生产环境 assertNotProduction 抛出错误', () => {
      process.env.NODE_ENV = 'production';
      expect(() => assertNotProduction(SYNTHETIC_JOB_DEFINITION)).toThrow(
        'Synthetic Job Definition detected in production',
      );
    });

    it('测试环境 assertNotProduction 不抛出', () => {
      process.env.NODE_ENV = 'test';
      expect(() => assertNotProduction(SYNTHETIC_JOB_DEFINITION)).not.toThrow();
    });
  });

  describe('Definition 合法性', () => {
    let registry: JobDefinitionRegistry;

    beforeEach(() => {
      registry = new JobDefinitionRegistry();
    });

    it('Synthetic Definition 可通过 Registry 注册', () => {
      registry.register(SYNTHETIC_JOB_DEFINITION);
      expect(registry.get('synthetic_job')).toBeDefined();
      expect(registry.has('synthetic_job')).toBe(true);
    });

    it('重复注册抛出 DuplicateJobTypeError', () => {
      registry.register(SYNTHETIC_JOB_DEFINITION);
      expect(() => registry.register(SYNTHETIC_JOB_DEFINITION)).toThrow(
        DuplicateJobTypeError,
      );
    });

    it('queueName 在允许列表中', () => {
      expect(ALLOWED_QUEUE_NAMES).toContain(SYNTHETIC_JOB_DEFINITION.queue.queueName);
    });

    it('timeoutMs 在合法范围 [1000, 600000]', () => {
      expect(SYNTHETIC_JOB_DEFINITION.execution.timeoutMs).toBeGreaterThanOrEqual(1000);
      expect(SYNTHETIC_JOB_DEFINITION.execution.timeoutMs).toBeLessThanOrEqual(600_000);
    });

    it('maxRetries 在合法范围 [0, 10]', () => {
      expect(SYNTHETIC_JOB_DEFINITION.execution.maxRetries).toBeGreaterThanOrEqual(0);
      expect(SYNTHETIC_JOB_DEFINITION.execution.maxRetries).toBeLessThanOrEqual(10);
    });

    it('input/output schema non-empty', () => {
      expect(SYNTHETIC_JOB_DEFINITION.input.schemaVersion).toBeTruthy();
      expect(SYNTHETIC_JOB_DEFINITION.output.schemaVersion).toBeTruthy();
    });

    it('projectorKey 指向 synthetic_projector', () => {
      expect(SYNTHETIC_JOB_DEFINITION.projectorKey).toBe('synthetic_projector');
    });

    it('cancellable=true（测试取消场景需要）', () => {
      expect(SYNTHETIC_JOB_DEFINITION.execution.cancellable).toBe(true);
    });
  });
});
