"use strict";
/**
 * Enhanced Deployment Configuration Generator
 *
 * Generates comprehensive deployment infrastructure including:
 * - Multi-region deployment configurations
 * - Edge function deployments (Cloudflare Workers, Lambda@Edge)
 * - Geo-routing and load balancing
 * - Disaster recovery and failover
 * - Database replication across regions
 * - Infrastructure as Code (Terraform/Pulumi)
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnhancedDeploymentGenerator = void 0;
const path = __importStar(require("path"));
class EnhancedDeploymentGenerator {
    id = 'enhanced-deployment';
    name = 'Enhanced Deployment Configuration Generator';
    description = 'Generates comprehensive deployment configuration including multi-region, edge functions, and disaster recovery';
    generate(context) {
        const { workflow, outputDirectory } = context;
        const files = [];
        if (!workflow.deployment) {
            return { files };
        }
        const deployment = workflow.deployment;
        const infraDir = path.join(outputDirectory, 'infrastructure');
        // Generate multi-region configuration
        if (deployment.strategy === 'multi_region' && deployment.regions) {
            files.push({
                path: path.join(infraDir, 'config/regions.ts'),
                content: this.generateRegionConfig(deployment),
            });
            files.push({
                path: path.join(infraDir, 'terraform/multi-region.tf'),
                content: this.generateMultiRegionTerraform(deployment),
            });
            files.push({
                path: path.join(infraDir, 'scripts/deploy-multi-region.sh'),
                content: this.generateMultiRegionDeployScript(deployment),
            });
        }
        // Generate edge function configuration
        if (deployment.edge_functions && deployment.edge_functions.length > 0) {
            files.push({
                path: path.join(infraDir, 'edge/edge-functions.ts'),
                content: this.generateEdgeFunctionsConfig(deployment),
            });
            deployment.edge_functions.forEach(edgeFunc => {
                const provider = edgeFunc.provider || 'cloudflare_workers';
                files.push({
                    path: path.join(infraDir, `edge/${edgeFunc.name}.ts`),
                    content: this.generateEdgeFunction(edgeFunc, provider),
                });
                if (provider === 'cloudflare_workers') {
                    files.push({
                        path: path.join(infraDir, `edge/${edgeFunc.name}.wrangler.toml`),
                        content: this.generateWranglerConfig(edgeFunc),
                    });
                }
                else if (provider === 'lambda_edge') {
                    files.push({
                        path: path.join(infraDir, `edge/${edgeFunc.name}.lambda.json`),
                        content: this.generateLambdaEdgeConfig(edgeFunc),
                    });
                }
            });
        }
        // Generate geo-routing configuration
        if (deployment.geo_routing?.enabled) {
            files.push({
                path: path.join(infraDir, 'routing/geo-router.ts'),
                content: this.generateGeoRouter(deployment),
            });
            files.push({
                path: path.join(infraDir, 'terraform/geo-routing.tf'),
                content: this.generateGeoRoutingTerraform(deployment),
            });
        }
        // Generate disaster recovery configuration
        if (deployment.disaster_recovery) {
            files.push({
                path: path.join(infraDir, 'dr/disaster-recovery.ts'),
                content: this.generateDisasterRecoveryConfig(deployment),
            });
            files.push({
                path: path.join(infraDir, 'dr/failover.ts'),
                content: this.generateFailoverLogic(deployment),
            });
            files.push({
                path: path.join(infraDir, 'scripts/failover.sh'),
                content: this.generateFailoverScript(deployment),
            });
            files.push({
                path: path.join(infraDir, 'terraform/disaster-recovery.tf'),
                content: this.generateDRTerraform(deployment),
            });
        }
        // Generate deployment utilities
        files.push({
            path: path.join(infraDir, 'utils/health-check.ts'),
            content: this.generateHealthCheck(deployment),
        });
        files.push({
            path: path.join(infraDir, 'utils/region-selector.ts'),
            content: this.generateRegionSelector(deployment),
        });
        // Generate deployment types
        files.push({
            path: path.join(infraDir, 'types/deployment.ts'),
            content: this.generateDeploymentTypes(deployment),
        });
        // Generate main infrastructure setup
        files.push({
            path: path.join(infraDir, 'terraform/main.tf'),
            content: this.generateMainTerraform(deployment),
        });
        files.push({
            path: path.join(infraDir, 'terraform/variables.tf'),
            content: this.generateTerraformVariables(deployment),
        });
        // Generate deployment documentation
        files.push({
            path: path.join(infraDir, 'README.md'),
            content: this.generateDeploymentDocs(deployment),
        });
        return { files };
    }
    generateRegionConfig(deployment) {
        const regions = deployment.regions || [];
        return `/**
 * Multi-Region Configuration
 * Strategy: ${deployment.strategy}
 */

export interface RegionConfig {
  name: string;
  primary: boolean;
  services: string[];
  endpoint: string;
  databaseReplica: boolean;
  priority: number;
}

export const regions: RegionConfig[] = ${JSON.stringify(regions.map((r, idx) => ({
            name: r.name,
            primary: r.primary || false,
            services: r.services,
            endpoint: `https://${r.name}.example.com`,
            databaseReplica: r.database_replica || false,
            priority: r.primary ? 1 : idx + 2,
        })), null, 2)};

export function getPrimaryRegion(): RegionConfig {
  const primary = regions.find(r => r.primary);
  if (!primary) {
    throw new Error('No primary region configured');
  }
  return primary;
}

export function getRegionByName(name: string): RegionConfig | undefined {
  return regions.find(r => r.name === name);
}

export function getActiveRegions(): RegionConfig[] {
  return regions.filter(r => r.services.length > 0);
}
`;
    }
    generateMultiRegionTerraform(deployment) {
        const regions = deployment.regions || [];
        return `/**
 * Terraform Configuration for Multi-Region Deployment
 */

terraform {
  required_version = ">= 1.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

${regions.map(region => `
# Region: ${region.name}
provider "aws" {
  alias  = "${region.name.replace(/-/g, '_')}"
  region = "${region.name}"
}

${region.services.map(service => `
resource "aws_ecs_cluster" "${region.name.replace(/-/g, '_')}_${service}" {
  provider = aws.${region.name.replace(/-/g, '_')}
  name     = "${service}-cluster-${region.name}"

  setting {
    name  = "containerInsights"
    value = "enabled"
  }

  tags = {
    Environment = var.environment
    Region      = "${region.name}"
    Service     = "${service}"
    Primary     = "${region.primary || false}"
  }
}
`).join('\n')}

${region.database_replica ? `
# Database Replica
resource "aws_db_instance" "${region.name.replace(/-/g, '_')}_replica" {
  provider               = aws.${region.name.replace(/-/g, '_')}
  replicate_source_db    = aws_db_instance.primary.identifier
  identifier             = "db-replica-${region.name}"
  instance_class         = var.db_instance_class
  publicly_accessible    = false
  skip_final_snapshot    = true

  tags = {
    Environment = var.environment
    Region      = "${region.name}"
    Type        = "replica"
  }
}
` : ''}
`).join('\n')}

# Load Balancer
resource "aws_lb" "global" {
  name               = "global-lb"
  internal           = false
  load_balancer_type = "application"

  enable_cross_zone_load_balancing = true
  enable_http2                     = true

  tags = {
    Environment = var.environment
  }
}
`;
    }
    generateMultiRegionDeployScript(deployment) {
        const regions = deployment.regions || [];
        return `#!/bin/bash
# Multi-Region Deployment Script

set -e

REGIONS=(${regions.map(r => `"${r.name}"`).join(' ')})
PRIMARY_REGION="${regions.find(r => r.primary)?.name || regions[0].name}"

echo "Starting multi-region deployment..."
echo "Primary region: $PRIMARY_REGION"

# Deploy to primary region first
echo "Deploying to primary region: $PRIMARY_REGION"
cd terraform
terraform init
terraform workspace select $PRIMARY_REGION || terraform workspace new $PRIMARY_REGION
terraform apply -var="region=$PRIMARY_REGION" -auto-approve

# Deploy to secondary regions
for region in "\${REGIONS[@]}"; do
  if [ "$region" != "$PRIMARY_REGION" ]; then
    echo "Deploying to secondary region: $region"
    terraform workspace select $region || terraform workspace new $region
    terraform apply -var="region=$region" -auto-approve
  fi
done

echo "Multi-region deployment complete!"
`;
    }
    generateEdgeFunctionsConfig(deployment) {
        const edgeFunctions = deployment.edge_functions || [];
        return `/**
 * Edge Functions Configuration
 */

export interface EdgeFunctionConfig {
  name: string;
  regions: string[] | 'all';
  provider: string;
  handler: string;
}

export const edgeFunctions: EdgeFunctionConfig[] = ${JSON.stringify(edgeFunctions, null, 2)};

export function getEdgeFunctionByName(name: string): EdgeFunctionConfig | undefined {
  return edgeFunctions.find(f => f.name === name);
}

export function getEdgeFunctionsForRegion(region: string): EdgeFunctionConfig[] {
  return edgeFunctions.filter(f => f.regions === 'all' || f.regions.includes(region));
}
`;
    }
    generateEdgeFunction(edgeFunc, provider) {
        if (provider === 'cloudflare_workers') {
            return this.generateCloudflareWorker(edgeFunc);
        }
        else if (provider === 'lambda_edge') {
            return this.generateLambdaEdge(edgeFunc);
        }
        return this.generateGenericEdgeFunction(edgeFunc);
    }
    generateCloudflareWorker(edgeFunc) {
        return `/**
 * Cloudflare Worker: ${edgeFunc.name}
 * Regions: ${edgeFunc.regions === 'all' ? 'All' : edgeFunc.regions.join(', ')}
 */

addEventListener('fetch', (event) => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request: Request): Promise<Response> {
  const url = new URL(request.url);

  // Add your edge logic here
  // Examples: A/B testing, geo-routing, authentication, caching

  // Get client location
  const country = request.headers.get('CF-IPCountry');
  const region = getRegionFromCountry(country);

  // Route to appropriate origin
  const originUrl = \`https://\${region}.example.com\${url.pathname}\`;

  // Fetch from origin
  const response = await fetch(originUrl, {
    method: request.method,
    headers: request.headers,
    body: request.body,
  });

  // Add edge headers
  const newResponse = new Response(response.body, response);
  newResponse.headers.set('X-Edge-Region', region);
  newResponse.headers.set('X-Edge-Function', '${edgeFunc.name}');

  return newResponse;
}

function getRegionFromCountry(country: string | null): string {
  // Map countries to regions
  const countryToRegion: Record<string, string> = {
    US: 'us-east-1',
    GB: 'eu-west-1',
    DE: 'eu-west-1',
    JP: 'ap-northeast-1',
    AU: 'ap-southeast-2',
  };

  return countryToRegion[country || 'US'] || 'us-east-1';
}
`;
    }
    generateLambdaEdge(edgeFunc) {
        return `/**
 * Lambda@Edge Function: ${edgeFunc.name}
 * Regions: ${edgeFunc.regions === 'all' ? 'All' : edgeFunc.regions.join(', ')}
 */

export const handler = async (event: any) => {
  const request = event.Records[0].cf.request;
  const headers = request.headers;

  // Add your edge logic here
  // Examples: Header manipulation, authentication, geo-routing

  // Get CloudFront viewer location
  const viewerCountry = headers['cloudfront-viewer-country']?.[0]?.value;
  const region = getRegionFromCountry(viewerCountry);

  // Modify origin
  request.origin = {
    custom: {
      domainName: \`\${region}.example.com\`,
      port: 443,
      protocol: 'https',
      path: '',
      sslProtocols: ['TLSv1.2'],
      readTimeout: 30,
      keepaliveTimeout: 5,
      customHeaders: {},
    },
  };

  // Add custom headers
  request.headers['x-edge-region'] = [{ key: 'X-Edge-Region', value: region }];
  request.headers['x-edge-function'] = [{ key: 'X-Edge-Function', value: '${edgeFunc.name}' }];

  return request;
};

function getRegionFromCountry(country: string | undefined): string {
  const countryToRegion: Record<string, string> = {
    US: 'us-east-1',
    GB: 'eu-west-1',
    DE: 'eu-west-1',
    JP: 'ap-northeast-1',
    AU: 'ap-southeast-2',
  };

  return countryToRegion[country || 'US'] || 'us-east-1';
}
`;
    }
    generateGenericEdgeFunction(edgeFunc) {
        return `/**
 * Edge Function: ${edgeFunc.name}
 */

export async function handler(request: Request): Promise<Response> {
  // Add your edge logic here
  return new Response('Edge function response', {
    headers: {
      'X-Edge-Function': '${edgeFunc.name}',
    },
  });
}
`;
    }
    generateWranglerConfig(edgeFunc) {
        return `name = "${edgeFunc.name}"
type = "javascript"
account_id = "\${CLOUDFLARE_ACCOUNT_ID}"
workers_dev = true
route = ""
zone_id = "\${CLOUDFLARE_ZONE_ID}"

[build]
command = "npm run build"

[build.upload]
format = "service-worker"

[[env.production]]
name = "${edgeFunc.name}-production"
route = "example.com/*"
`;
    }
    generateLambdaEdgeConfig(edgeFunc) {
        return JSON.stringify({
            name: edgeFunc.name,
            runtime: 'nodejs18.x',
            handler: 'index.handler',
            role: 'arn:aws:iam::ACCOUNT_ID:role/lambda-edge-role',
            timeout: 5,
            memorySize: 128,
            environment: {
                variables: {},
            },
        }, null, 2);
    }
    generateGeoRouter(deployment) {
        const strategy = deployment.geo_routing?.strategy || 'closest_region';
        return `/**
 * Geo-Routing Logic
 * Strategy: ${strategy}
 */

import { regions, RegionConfig } from '../config/regions';

export class GeoRouter {
  /**
   * Select the best region for a client based on geo-routing strategy
   */
  selectRegion(clientIp: string, clientCountry?: string): RegionConfig {
    switch ('${strategy}') {
      case 'lowest_latency':
        return this.selectByLatency(clientIp);
      case 'closest_region':
        return this.selectByProximity(clientCountry);
      case 'manual':
        return this.selectManual(clientCountry);
      default:
        return this.selectByProximity(clientCountry);
    }
  }

  private selectByLatency(clientIp: string): RegionConfig {
    // In production, this would measure actual latency to each region
    // For now, return primary region
    return regions.find(r => r.primary) || regions[0];
  }

  private selectByProximity(clientCountry?: string): RegionConfig {
    const countryToRegion: Record<string, string> = {
      US: 'us-east-1',
      CA: 'us-east-1',
      GB: 'eu-west-1',
      DE: 'eu-west-1',
      FR: 'eu-west-1',
      JP: 'ap-northeast-1',
      CN: 'ap-northeast-1',
      AU: 'ap-southeast-2',
      BR: 'sa-east-1',
    };

    const regionName = countryToRegion[clientCountry || 'US'];
    return regions.find(r => r.name === regionName) || regions.find(r => r.primary) || regions[0];
  }

  private selectManual(clientCountry?: string): RegionConfig {
    // Manual routing rules can be defined here
    return regions.find(r => r.primary) || regions[0];
  }

  /**
   * Get health status of all regions
   */
  async getRegionHealth(): Promise<Record<string, boolean>> {
    const health: Record<string, boolean> = {};

    for (const region of regions) {
      try {
        const response = await fetch(\`\${region.endpoint}/health\`, { signal: AbortSignal.timeout(5000) });
        health[region.name] = response.ok;
      } catch (error) {
        health[region.name] = false;
      }
    }

    return health;
  }

  /**
   * Get healthy regions only
   */
  async getHealthyRegions(): Promise<RegionConfig[]> {
    const health = await this.getRegionHealth();
    return regions.filter(r => health[r.name]);
  }
}

export const geoRouter = new GeoRouter();
`;
    }
    generateGeoRoutingTerraform(deployment) {
        return `/**
 * Geo-Routing Infrastructure
 */

# Route 53 Health Checks
${(deployment.regions || []).map(region => `
resource "aws_route53_health_check" "${region.name.replace(/-/g, '_')}" {
  fqdn              = "${region.name}.example.com"
  port              = 443
  type              = "HTTPS"
  resource_path     = "/health"
  failure_threshold = "3"
  request_interval  = "30"

  tags = {
    Name = "${region.name}-health-check"
  }
}
`).join('\n')}

# Route 53 Geolocation Routing
resource "aws_route53_zone" "main" {
  name = "example.com"
}

${(deployment.regions || []).map(region => `
resource "aws_route53_record" "${region.name.replace(/-/g, '_')}" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "example.com"
  type    = "A"

  set_identifier = "${region.name}"

  geolocation_routing_policy {
    continent = "${this.getContinent(region.name)}"
  }

  alias {
    name                   = aws_lb.${region.name.replace(/-/g, '_')}.dns_name
    zone_id                = aws_lb.${region.name.replace(/-/g, '_')}.zone_id
    evaluate_target_health = true
  }

  health_check_id = aws_route53_health_check.${region.name.replace(/-/g, '_')}.id
}
`).join('\n')}
`;
    }
    getContinent(region) {
        if (region.startsWith('us-'))
            return 'NA';
        if (region.startsWith('eu-'))
            return 'EU';
        if (region.startsWith('ap-'))
            return 'AS';
        if (region.startsWith('sa-'))
            return 'SA';
        return 'NA';
    }
    generateDisasterRecoveryConfig(deployment) {
        const dr = deployment.disaster_recovery;
        return `/**
 * Disaster Recovery Configuration
 * RPO: ${dr.rpo}
 * RTO: ${dr.rto}
 * Failover: ${dr.failover}
 */

export interface DisasterRecoveryConfig {
  rpo: string; // Recovery Point Objective
  rto: string; // Recovery Time Objective
  replicaRegions: string[];
  failover: 'automatic' | 'manual';
  backupRetention: number; // days
}

export const drConfig: DisasterRecoveryConfig = {
  rpo: '${dr.rpo}',
  rto: '${dr.rto}',
  replicaRegions: ${JSON.stringify(dr.replica_regions || [])},
  failover: '${dr.failover}',
  backupRetention: 30,
};

export class DisasterRecoveryManager {
  /**
   * Check if system meets RPO requirements
   */
  async checkRPO(): Promise<boolean> {
    // Check last backup time
    const lastBackup = await this.getLastBackupTime();
    const rpoMinutes = this.parseTimeToMinutes(drConfig.rpo);
    const timeSinceBackup = (Date.now() - lastBackup.getTime()) / 1000 / 60;

    return timeSinceBackup <= rpoMinutes;
  }

  /**
   * Estimate recovery time
   */
  async estimateRecoveryTime(): Promise<number> {
    // Estimate time to restore from backup and bring systems online
    const rtoMinutes = this.parseTimeToMinutes(drConfig.rto);
    return rtoMinutes;
  }

  /**
   * Trigger disaster recovery
   */
  async triggerDR(targetRegion: string): Promise<void> {
    console.log(\`Initiating disaster recovery to \${targetRegion}\`);

    // 1. Stop writes to primary
    await this.stopWritesToPrimary();

    // 2. Promote replica to primary
    await this.promoteReplica(targetRegion);

    // 3. Update DNS to point to new primary
    await this.updateDNS(targetRegion);

    // 4. Verify new primary is healthy
    await this.verifyNewPrimary(targetRegion);

    console.log('Disaster recovery complete');
  }

  private async getLastBackupTime(): Promise<Date> {
    // Implementation depends on backup system
    return new Date();
  }

  private parseTimeToMinutes(time: string): number {
    // Parse strings like "1_hour", "30_minutes", "1_day"
    const [value, unit] = time.split('_');
    const num = parseInt(value, 10);

    switch (unit) {
      case 'minute':
      case 'minutes':
        return num;
      case 'hour':
      case 'hours':
        return num * 60;
      case 'day':
      case 'days':
        return num * 24 * 60;
      default:
        return num;
    }
  }

  private async stopWritesToPrimary(): Promise<void> {
    // Set database to read-only mode
  }

  private async promoteReplica(region: string): Promise<void> {
    // Promote database replica to primary
  }

  private async updateDNS(region: string): Promise<void> {
    // Update Route 53 to point to new region
  }

  private async verifyNewPrimary(region: string): Promise<void> {
    // Health check on new primary
  }
}
`;
    }
    generateFailoverLogic(deployment) {
        const dr = deployment.disaster_recovery;
        const isAutomatic = dr.failover === 'automatic';
        return `/**
 * Automatic Failover Logic
 * Mode: ${dr.failover}
 */

import { geoRouter } from '../routing/geo-router';
import { DisasterRecoveryManager } from './disaster-recovery';

export class FailoverManager {
  private drManager = new DisasterRecoveryManager();
  private healthCheckInterval = 30000; // 30 seconds
  private failureThreshold = 3;
  private consecutiveFailures = new Map<string, number>();

  ${isAutomatic ? `
  /**
   * Start automatic health monitoring and failover
   */
  startMonitoring(): void {
    setInterval(() => {
      this.checkHealth();
    }, this.healthCheckInterval);
  }

  private async checkHealth(): Promise<void> {
    const health = await geoRouter.getRegionHealth();

    for (const [region, isHealthy] of Object.entries(health)) {
      if (!isHealthy) {
        const failures = (this.consecutiveFailures.get(region) || 0) + 1;
        this.consecutiveFailures.set(region, failures);

        if (failures >= this.failureThreshold) {
          await this.triggerAutomaticFailover(region);
        }
      } else {
        this.consecutiveFailures.set(region, 0);
      }
    }
  }

  private async triggerAutomaticFailover(failedRegion: string): Promise<void> {
    console.error(\`Region \${failedRegion} has failed health checks. Triggering automatic failover.\`);

    // Select healthy region
    const healthyRegions = await geoRouter.getHealthyRegions();
    if (healthyRegions.length === 0) {
      console.error('No healthy regions available for failover!');
      return;
    }

    const targetRegion = healthyRegions[0].name;
    await this.drManager.triggerDR(targetRegion);
  }
  ` : `
  /**
   * Manual failover - requires operator confirmation
   */
  async initiateManualFailover(targetRegion: string): Promise<void> {
    console.log(\`Manual failover requested to \${targetRegion}\`);
    console.log('Operator confirmation required.');

    // In production, this would require manual approval
    // For now, proceed with failover
    await this.drManager.triggerDR(targetRegion);
  }
  `}
}

export const failoverManager = new FailoverManager();
`;
    }
    generateFailoverScript(_deployment) {
        return `#!/bin/bash
# Disaster Recovery Failover Script

set -e

TARGET_REGION=\${1:-"us-west-2"}

echo "====================================="
echo "Disaster Recovery Failover"
echo "====================================="
echo "Target Region: $TARGET_REGION"
echo ""

# Confirm
read -p "Are you sure you want to failover to $TARGET_REGION? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
  echo "Failover cancelled"
  exit 0
fi

echo "Starting failover process..."

# 1. Promote database replica
echo "Step 1/4: Promoting database replica in $TARGET_REGION"
aws rds promote-read-replica --db-instance-identifier db-replica-$TARGET_REGION --region $TARGET_REGION

# 2. Update DNS
echo "Step 2/4: Updating DNS to point to $TARGET_REGION"
# Update Route 53 records

# 3. Update application configuration
echo "Step 3/4: Updating application configuration"
# Update environment variables, config files, etc.

# 4. Verify health
echo "Step 4/4: Verifying health of new primary region"
curl -f https://$TARGET_REGION.example.com/health || {
  echo "Health check failed!"
  exit 1
}

echo ""
echo "Failover complete! New primary region: $TARGET_REGION"
`;
    }
    generateDRTerraform(deployment) {
        const dr = deployment.disaster_recovery;
        return `/**
 * Disaster Recovery Infrastructure
 */

# Automated Backups
resource "aws_db_instance" "primary" {
  identifier          = "primary-db"
  engine              = "postgres"
  instance_class      = var.db_instance_class

  backup_retention_period = 30
  backup_window          = "03:00-04:00"

  enabled_cloudwatch_logs_exports = ["postgresql"]

  tags = {
    Environment = var.environment
    Type        = "primary"
  }
}

${(dr.replica_regions || []).map(region => `
# Replica in ${region}
resource "aws_db_instance" "${region.replace(/-/g, '_')}_replica" {
  provider               = aws.${region.replace(/-/g, '_')}
  replicate_source_db    = aws_db_instance.primary.identifier
  identifier             = "db-replica-${region}"
  instance_class         = var.db_instance_class

  backup_retention_period = 30
  skip_final_snapshot    = false
  final_snapshot_identifier = "db-replica-${region}-final"

  tags = {
    Environment = var.environment
    Region      = "${region}"
    Type        = "dr-replica"
  }
}
`).join('\n')}

# CloudWatch Alarms for Automatic Failover
${dr.failover === 'automatic' ? `
resource "aws_cloudwatch_metric_alarm" "database_connection_failure" {
  alarm_name          = "database-connection-failure"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "2"
  metric_name         = "DatabaseConnections"
  namespace           = "AWS/RDS"
  period              = "60"
  statistic           = "Average"
  threshold           = "0"
  alarm_description   = "Trigger failover if database connections drop"

  alarm_actions = [aws_sns_topic.dr_alerts.arn]
}

resource "aws_sns_topic" "dr_alerts" {
  name = "disaster-recovery-alerts"
}
` : ''}
`;
    }
    generateHealthCheck(_deployment) {
        return `/**
 * Health Check Utilities
 */

export interface HealthStatus {
  region: string;
  healthy: boolean;
  latency: number;
  lastCheck: Date;
  services: Record<string, boolean>;
}

export async function checkRegionHealth(region: string, endpoint: string): Promise<HealthStatus> {
  const startTime = Date.now();
  const services: Record<string, boolean> = {};

  try {
    // Check main application
    const response = await fetch(\`\${endpoint}/health\`, { signal: AbortSignal.timeout(5000) });
    const latency = Date.now() - startTime;

    if (response.ok) {
      const data = await response.json();
      services.api = data.status === 'healthy';
      services.database = data.database === 'connected';
      services.cache = data.cache === 'connected';
    }

    const allHealthy = Object.values(services).every(s => s);

    return {
      region,
      healthy: allHealthy,
      latency,
      lastCheck: new Date(),
      services,
    };
  } catch (error) {
    return {
      region,
      healthy: false,
      latency: Date.now() - startTime,
      lastCheck: new Date(),
      services: {},
    };
  }
}
`;
    }
    generateRegionSelector(_deployment) {
        return `/**
 * Region Selection Utilities
 */

import { regions, RegionConfig } from '../config/regions';

export class RegionSelector {
  /**
   * Select region based on client IP and preferences
   */
  selectForClient(clientIp: string, clientCountry?: string, preferredRegion?: string): RegionConfig {
    // If client specifies preferred region, use it if available
    if (preferredRegion) {
      const region = regions.find(r => r.name === preferredRegion);
      if (region) {
        return region;
      }
    }

    // Otherwise, use geo-routing
    return this.selectByGeo(clientCountry);
  }

  private selectByGeo(clientCountry?: string): RegionConfig {
    const countryToRegion: Record<string, string> = {
      US: 'us-east-1',
      GB: 'eu-west-1',
      JP: 'ap-northeast-1',
    };

    const regionName = countryToRegion[clientCountry || 'US'];
    return regions.find(r => r.name === regionName) || regions[0];
  }
}
`;
    }
    generateDeploymentTypes(_deployment) {
        return `/**
 * Deployment Type Definitions
 */

export type DeploymentStrategy = 'single_region' | 'multi_region' | 'edge';

export interface Region {
  name: string;
  primary: boolean;
  services: string[];
  endpoint: string;
  databaseReplica: boolean;
}

export interface EdgeFunction {
  name: string;
  regions: string[] | 'all';
  provider: 'cloudflare_workers' | 'lambda_edge' | string;
  handler: string;
}

export interface GeoRoutingStrategy {
  enabled: boolean;
  strategy: 'lowest_latency' | 'closest_region' | 'manual';
}

export interface DisasterRecovery {
  rpo: string;
  rto: string;
  replicaRegions: string[];
  failover: 'automatic' | 'manual';
}
`;
    }
    generateMainTerraform(_deployment) {
        return `/**
 * Main Terraform Configuration
 */

terraform {
  required_version = ">= 1.0"

  backend "s3" {
    bucket = "terraform-state-bucket"
    key    = "infrastructure/terraform.tfstate"
    region = "us-east-1"
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.primary_region
}

# VPC Configuration
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name        = "main-vpc"
    Environment = var.environment
  }
}

# Outputs
output "vpc_id" {
  value = aws_vpc.main.id
}
`;
    }
    generateTerraformVariables(deployment) {
        return `/**
 * Terraform Variables
 */

variable "environment" {
  description = "Environment name"
  type        = string
  default     = "production"
}

variable "primary_region" {
  description = "Primary AWS region"
  type        = string
  default     = "${deployment.regions?.find(r => r.primary)?.name || 'us-east-1'}"
}

variable "db_instance_class" {
  description = "RDS instance class"
  type        = string
  default     = "db.t3.medium"
}

variable "enable_dr" {
  description = "Enable disaster recovery"
  type        = bool
  default     = ${!!deployment.disaster_recovery}
}
`;
    }
    generateDeploymentDocs(deployment) {
        return `# Deployment Infrastructure

## Overview

This directory contains the infrastructure configuration for deploying the application.

**Strategy**: ${deployment.strategy}

## Architecture

${deployment.strategy === 'multi_region' ? `
### Multi-Region Deployment

The application is deployed across multiple regions for high availability:

${(deployment.regions || []).map(r => `- **${r.name}** ${r.primary ? '(Primary)' : ''}
  - Services: ${r.services.join(', ')}
  - Database Replica: ${r.database_replica ? 'Yes' : 'No'}`).join('\n')}
` : ''}

${deployment.edge_functions && deployment.edge_functions.length > 0 ? `
### Edge Functions

Edge functions are deployed for low-latency operations:

${deployment.edge_functions.map(f => `- **${f.name}**
  - Provider: ${f.provider || 'cloudflare_workers'}
  - Regions: ${f.regions === 'all' ? 'All' : f.regions.join(', ')}`).join('\n')}
` : ''}

${deployment.disaster_recovery ? `
### Disaster Recovery

- **RPO**: ${deployment.disaster_recovery.rpo}
- **RTO**: ${deployment.disaster_recovery.rto}
- **Failover**: ${deployment.disaster_recovery.failover}
- **Replica Regions**: ${deployment.disaster_recovery.replica_regions?.join(', ') || 'None'}
` : ''}

## Deployment

### Prerequisites

- Terraform >= 1.0
- AWS CLI configured
- Appropriate IAM permissions

### Deploy to Production

\`\`\`bash
cd infrastructure/terraform
terraform init
terraform plan
terraform apply
\`\`\`

${deployment.strategy === 'multi_region' ? `
### Multi-Region Deployment

\`\`\`bash
./scripts/deploy-multi-region.sh
\`\`\`
` : ''}

${deployment.disaster_recovery ? `
## Disaster Recovery

### Trigger Failover

\`\`\`bash
./scripts/failover.sh <target-region>
\`\`\`

### Verify DR Configuration

\`\`\`bash
# Check RPO compliance
npm run dr:check-rpo

# Test failover (dry run)
npm run dr:test-failover
\`\`\`
` : ''}

## Monitoring

Health checks are configured for all regions. Monitor via:

- CloudWatch Dashboards
- Route 53 Health Checks
- Custom health check endpoints

## Support

For deployment issues, contact the DevOps team.
`;
    }
}
exports.EnhancedDeploymentGenerator = EnhancedDeploymentGenerator;
//# sourceMappingURL=enhanced-deployment-generator.js.map