/**
 * Tests for Enhanced Rate Limiting Generator
 */

import { EnhancedRateLimitingGenerator } from './enhanced-rate-limiting-generator';
import { GeneratorContext } from '../types';
import { Workflow } from '../../types/workflow';

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

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

  describe('Configuration Generation', () => {
    it('should generate rate limiting configuration', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        rate_limiting: {
          middleware: true,
          storage: {
            type: 'redis',
            redis_url: 'redis://localhost:6379',
          },
          strategy: 'sliding_window',
          per_user: {
            requests: 100,
            window: '1m',
          },
        },
      };

      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/rate-limiting.ts'));
      expect(configFile).toBeDefined();
      expect(configFile!.content).toContain('sliding_window');
      expect(configFile!.content).toContain('redis');
    });
  });

  describe('Middleware Generation', () => {
    it('should generate rate limit middleware', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        rate_limiting: {
          middleware: true,
        },
      };

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

      const result = generator.generate(context);

      const middlewareFile = result.files.find(f => f.path.includes('middleware/rate-limit.ts'));
      expect(middlewareFile).toBeDefined();
      expect(middlewareFile!.content).toContain('rateLimit');
      expect(middlewareFile!.content).toContain('rateLimitPerUser');
    });
  });

  describe('Storage Backends', () => {
    it('should generate Redis store', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        rate_limiting: {
          storage: {
            type: 'redis',
            redis_url: 'redis://localhost:6379',
          },
        },
      };

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

      const result = generator.generate(context);

      const storeFile = result.files.find(f => f.path.includes('rate-limit-store.ts'));
      expect(storeFile).toBeDefined();
      expect(storeFile!.content).toContain('Redis');
      expect(storeFile!.content).toContain('ioredis');
    });

    it('should generate memory store', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        rate_limiting: {
          storage: {
            type: 'memory',
          },
        },
      };

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

      const result = generator.generate(context);

      const storeFile = result.files.find(f => f.path.includes('rate-limit-store.ts'));
      expect(storeFile).toBeDefined();
      expect(storeFile!.content).toContain('Map<string, StoreEntry>');
    });
  });

  describe('Strategies', () => {
    it('should generate rate limit strategies', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0', name: 'Test', description: 'Test workflow' },
        stack: {},
        rate_limiting: {
          strategy: 'sliding_window',
        },
      };

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

      const result = generator.generate(context);

      const strategiesFile = result.files.find(f => f.path.includes('rate-limit-strategies.ts'));
      expect(strategiesFile).toBeDefined();
      expect(strategiesFile!.content).toContain('SlidingWindowStrategy');
      expect(strategiesFile!.content).toContain('FixedWindowStrategy');
      expect(strategiesFile!.content).toContain('TokenBucketStrategy');
    });
  });

  describe('Edge Cases', () => {
    it('should return empty array when rate_limiting 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([]);
    });
  });
});
