/**
 * Tests for Enhanced Deployment Generator
 */

import { EnhancedDeploymentGenerator } from './enhanced-deployment-generator';
import { Workflow } from '../../types/workflow';

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

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

  it('should have correct metadata', () => {
    expect(generator.id).toBe('enhanced-deployment');
    expect(generator.name).toBe('Enhanced Deployment Configuration Generator');
    expect(generator.description).toContain('deployment');
  });

  it('should return empty result when no deployment config', () => {
    const workflow: Workflow = {
      workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
      stack: { api: { type: 'backend', technology: 'typescript/express' } },
      stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
    };

    const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
    expect(result.files).toHaveLength(0);
  });

  describe('Multi-Region Deployment', () => {
    it('should generate multi-region configuration', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [
            { name: 'us-east-1', primary: true, services: ['api'], database_replica: false },
            { name: 'eu-west-1', services: ['api'], database_replica: true },
          ],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const regionConfig = result.files.find(f => f.path.includes('config/regions.ts'));

      expect(regionConfig).toBeDefined();
      expect(regionConfig!.content).toContain('us-east-1');
      expect(regionConfig!.content).toContain('eu-west-1');
      expect(regionConfig!.content).toContain('getPrimaryRegion');
    });

    it('should generate Terraform for multi-region', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const terraform = result.files.find(f => f.path.includes('terraform/multi-region.tf'));

      expect(terraform).toBeDefined();
      expect(terraform!.content).toContain('aws_ecs_cluster');
    });

    it('should generate deployment script', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const script = result.files.find(f => f.path.includes('scripts/deploy-multi-region.sh'));

      expect(script).toBeDefined();
      expect(script!.content).toContain('#!/bin/bash');
      expect(script!.content).toContain('terraform');
    });
  });

  describe('Edge Functions', () => {
    it('should generate Cloudflare Workers', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'edge',
          edge_functions: [
            { name: 'geo-router', regions: 'all', provider: 'cloudflare_workers' },
          ],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const edgeFunc = result.files.find(f => f.path.includes('edge/geo-router.ts'));

      expect(edgeFunc).toBeDefined();
      expect(edgeFunc!.content).toContain('addEventListener');
      expect(edgeFunc!.content).toContain('handleRequest');
    });

    it('should generate Wrangler config', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'edge',
          edge_functions: [{ name: 'test-func', regions: 'all', provider: 'cloudflare_workers' }],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const wrangler = result.files.find(f => f.path.includes('test-func.wrangler.toml'));

      expect(wrangler).toBeDefined();
      expect(wrangler!.content).toContain('name = "test-func"');
    });

    it('should generate Lambda@Edge functions', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'edge',
          edge_functions: [{ name: 'lambda-func', regions: 'all', provider: 'lambda_edge' }],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const lambdaFunc = result.files.find(f => f.path.includes('edge/lambda-func.ts'));

      expect(lambdaFunc).toBeDefined();
      expect(lambdaFunc!.content).toContain('handler');
      expect(lambdaFunc!.content).toContain('cloudfront');
    });
  });

  describe('Geo-Routing', () => {
    it('should generate geo-router', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
          geo_routing: { enabled: true, strategy: 'closest_region' },
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const geoRouter = result.files.find(f => f.path.includes('routing/geo-router.ts'));

      expect(geoRouter).toBeDefined();
      expect(geoRouter!.content).toContain('GeoRouter');
      expect(geoRouter!.content).toContain('selectRegion');
    });

    it('should generate geo-routing Terraform', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
          geo_routing: { enabled: true, strategy: 'lowest_latency' },
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const terraform = result.files.find(f => f.path.includes('terraform/geo-routing.tf'));

      expect(terraform).toBeDefined();
      expect(terraform!.content).toContain('aws_route53_health_check');
    });
  });

  describe('Disaster Recovery', () => {
    it('should generate DR configuration', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
          disaster_recovery: {
            rpo: '1_hour',
            rto: '4_hours',
            replica_regions: ['us-west-2'],
            failover: 'automatic',
          },
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const drConfig = result.files.find(f => f.path.includes('dr/disaster-recovery.ts'));

      expect(drConfig).toBeDefined();
      expect(drConfig!.content).toContain('DisasterRecoveryManager');
      expect(drConfig!.content).toContain('checkRPO');
      expect(drConfig!.content).toContain('triggerDR');
    });

    it('should generate automatic failover', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
          disaster_recovery: { rpo: '1_hour', rto: '4_hours', failover: 'automatic' },
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const failover = result.files.find(f => f.path.includes('dr/failover.ts'));

      expect(failover).toBeDefined();
      expect(failover!.content).toContain('startMonitoring');
      expect(failover!.content).toContain('triggerAutomaticFailover');
    });

    it('should generate manual failover', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
          disaster_recovery: { rpo: '1_hour', rto: '4_hours', failover: 'manual' },
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const failover = result.files.find(f => f.path.includes('dr/failover.ts'));

      expect(failover!.content).toContain('initiateManualFailover');
    });

    it('should generate DR Terraform', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
          disaster_recovery: {
            rpo: '1_hour',
            rto: '4_hours',
            replica_regions: ['us-west-2'],
            failover: 'automatic',
          },
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const terraform = result.files.find(f => f.path.includes('terraform/disaster-recovery.tf'));

      expect(terraform).toBeDefined();
      expect(terraform!.content).toContain('aws_db_instance');
    });

    it('should generate failover script', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
          disaster_recovery: { rpo: '1_hour', rto: '4_hours', failover: 'manual' },
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const script = result.files.find(f => f.path.includes('scripts/failover.sh'));

      expect(script).toBeDefined();
      expect(script!.content).toContain('#!/bin/bash');
      expect(script!.content).toContain('promote-read-replica');
    });
  });

  describe('Infrastructure Files', () => {
    it('should generate health check utility', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const healthCheck = result.files.find(f => f.path.includes('utils/health-check.ts'));

      expect(healthCheck).toBeDefined();
      expect(healthCheck!.content).toContain('checkRegionHealth');
    });

    it('should generate deployment types', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: { strategy: 'single_region' },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const types = result.files.find(f => f.path.includes('types/deployment.ts'));

      expect(types).toBeDefined();
      expect(types!.content).toContain('DeploymentStrategy');
    });

    it('should generate main Terraform', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const terraform = result.files.find(f => f.path.includes('terraform/main.tf'));

      expect(terraform).toBeDefined();
      expect(terraform!.content).toContain('terraform');
    });

    it('should generate deployment documentation', () => {
      const workflow: Workflow = {
        workflow: { id: 'test', version: '1.0.0', name: 'Test', description: 'Test workflow' },
        stack: { api: { type: 'backend', technology: 'typescript/express' } },
        deployment: {
          strategy: 'multi_region',
          regions: [{ name: 'us-east-1', primary: true, services: ['api'] }],
        },
        stages: { local: { infrastructure: { databases: { primary: 'postgresql://localhost/test' }, services: {} } } },
      };

      const result = generator.generate({ workflow, outputDirectory: '/tmp/test' , executionPlan: { workflow, componentPlans: new Map() } });
      const docs = result.files.find(f => f.path.includes('README.md'));

      expect(docs).toBeDefined();
      expect(docs!.content).toContain('# Deployment Infrastructure');
    });
  });
});
