/**
 * Tests for Enhanced Background Jobs Generator
 */

import { EnhancedBackgroundJobsGenerator } from './enhanced-background-jobs-generator';
import { GeneratorContext } from '../types';
import { Workflow } from '../../types/workflow';

describe('EnhancedBackgroundJobsGenerator', () => {
  let generator: EnhancedBackgroundJobsGenerator;

  beforeEach(() => {
    generator = new EnhancedBackgroundJobsGenerator();
  });

  describe('Configuration Generation', () => {
    it('should generate job configuration', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        background_jobs: {
          provider: 'bullmq',
          redis: {
            url: 'redis://localhost:6379',
          },
        },
      };

      const context: GeneratorContext = { workflow, outputDirectory: '/tmp/test',
        executionPlan: { workflow, componentPlans: new Map() },
      };

      const result = generator.generate(context);

      expect(result.files.length).toBeGreaterThan(0);
      const configFile = result.files.find(f => f.path.includes('config/jobs.ts'));
      expect(configFile).toBeDefined();
      expect(configFile!.content).toContain('bullmq');
    });
  });

  describe('Job Queue', () => {
    it('should generate job queue', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        background_jobs: {
          provider: 'bullmq',
        },
      };

      const context: GeneratorContext = { workflow, outputDirectory: '/tmp/test',
        executionPlan: { workflow, componentPlans: new Map() },
      };

      const result = generator.generate(context);

      const queueFile = result.files.find(f => f.path.includes('job-queue.ts'));
      expect(queueFile).toBeDefined();
      expect(queueFile!.content).toContain('Queue');
      expect(queueFile!.content).toContain('addJob');
    });
  });

  describe('Job Handlers', () => {
    it('should generate job handlers', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        background_jobs: {
          provider: 'bullmq',
          jobs: [
            {
              name: 'SendEmail',
              handler: 'sendEmailHandler',
              concurrency: 5,
            },
          ],
        },
      };

      const context: GeneratorContext = { workflow, outputDirectory: '/tmp/test',
        executionPlan: { workflow, componentPlans: new Map() },
      };

      const result = generator.generate(context);

      const handlerFile = result.files.find(f => f.path.includes('sendemail-handler.ts'));
      expect(handlerFile).toBeDefined();
      expect(handlerFile!.content).toContain('processSendEmail');
    });
  });

  describe('Job Worker', () => {
    it('should generate job worker', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        background_jobs: {
          provider: 'bullmq',
          jobs: [
            {
              name: 'SendEmail',
              handler: 'sendEmailHandler',
            },
          ],
        },
      };

      const context: GeneratorContext = { workflow, outputDirectory: '/tmp/test',
        executionPlan: { workflow, componentPlans: new Map() },
      };

      const result = generator.generate(context);

      const workerFile = result.files.find(f => f.path.includes('job-worker.ts'));
      expect(workerFile).toBeDefined();
      expect(workerFile!.content).toContain('Worker');
      expect(workerFile!.content).toContain('SendEmail');
    });
  });

  describe('Cron Jobs', () => {
    it('should generate cron scheduler', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        background_jobs: {
          provider: 'bullmq',
          cron_jobs: [
            {
              name: 'DailyReport',
              schedule: '0 0 * * *',
              handler: 'generateDailyReport',
              timezone: 'America/New_York',
            },
          ],
        },
      };

      const context: GeneratorContext = { workflow, outputDirectory: '/tmp/test',
        executionPlan: { workflow, componentPlans: new Map() },
      };

      const result = generator.generate(context);

      const cronFile = result.files.find(f => f.path.includes('cron-scheduler.ts'));
      expect(cronFile).toBeDefined();
      expect(cronFile!.content).toContain('cron.schedule');
      expect(cronFile!.content).toContain('DailyReport');
    });
  });

  describe('Dashboard', () => {
    it('should generate dashboard when enabled', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        background_jobs: {
          provider: 'bullmq',
          dashboard: {
            enabled: true,
            port: 3001,
          },
        },
      };

      const context: GeneratorContext = { workflow, outputDirectory: '/tmp/test',
        executionPlan: { workflow, componentPlans: new Map() },
      };

      const result = generator.generate(context);

      const dashboardFile = result.files.find(f => f.path.includes('job-dashboard.ts'));
      expect(dashboardFile).toBeDefined();
      expect(dashboardFile!.content).toContain('@bull-board');
    });
  });

  describe('Dead Letter Queue', () => {
    it('should generate dead letter queue when enabled', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        background_jobs: {
          provider: 'bullmq',
          dead_letter_queue: {
            enabled: true,
            retention: '7d',
          },
        },
      };

      const context: GeneratorContext = { workflow, outputDirectory: '/tmp/test',
        executionPlan: { workflow, componentPlans: new Map() },
      };

      const result = generator.generate(context);

      const dlqFile = result.files.find(f => f.path.includes('dead-letter-queue.ts'));
      expect(dlqFile).toBeDefined();
      expect(dlqFile!.content).toContain('deadLetterQueue');
    });
  });

  describe('Edge Cases', () => {
    it('should return empty array when background_jobs not configured', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
      };

      const context: GeneratorContext = { workflow, outputDirectory: '/tmp/test',
        executionPlan: { workflow, componentPlans: new Map() },
      };

      const result = generator.generate(context);

      expect(result.files).toEqual([]);
    });
  });
});
