# Multi-Region High Availability Workspace
# Global deployment across 3 providers and 3 geographic regions
#
# Architecture:
# - US East (DigitalOcean NYC): Primary region, active serving
# - EU Central (Hetzner Germany): Secondary region, active serving + read replicas
# - Asia Pacific (AWS Singapore): Tertiary region, active serving + read replicas
#
# Features:
# - Geographic load balancing with Route53
# - Multi-master database replication
# - Automatic failover
# - Zero downtime deployment
# - Cost: ~$250/month across all regions

let hetzner = import "../../../extensions/providers/hetzner/nickel/main.ncl" in
let aws = import "../../../extensions/providers/aws/nickel/main.ncl" in
let digitalocean = import "../../../extensions/providers/digitalocean/nickel/main.ncl" in

{
  workspace_name = "multi-region-ha",
  description = "High availability deployment across 3 geographic regions",
  version = "1.0",

  environment = "production",
  owner = "platform-team",

  tags = {
    "project" = "global-app",
    "deployment" = "multi-region-ha",
    "environment" = "production"
  },

  # =============================================================================
  # Global Configuration
  # =============================================================================

  global_config = {
    dns_provider = "route53",
    health_check_interval = 30,
    failover_ttl = 60,
    replication_lag_tolerance = 300,
    rpo_target = 300,
    rto_target = 900
  },

  # =============================================================================
  # US EAST REGION (DigitalOcean NYC) - PRIMARY
  # =============================================================================

  region_us_east = {
    name = "us-east",
    provider = "digitalocean",
    region_code = "nyc3",
    primary = true,
    description = "Primary region: serves North America",

    # Private Network
    vpc = digitalocean.VPC & {
      name = "us-east-vpc",
      region = "nyc3",
      ip_range = "10.0.0.0/16"
    },

    # Application Servers (3 replicas for HA)
    app_servers = digitalocean.Droplet & {
      name = "us-app",
      region = "nyc3",
      size = "s-2vcpu-4gb",
      image = "ubuntu-22-04-x64",
      count = 3,
      vpc_uuid = "{{ region_us_east.vpc.id }}",
      backups = true,
      monitoring = true,
      tags = ["us-east", "primary", "production"]
    },

    # Load Balancer
    load_balancer = digitalocean.LoadBalancer & {
      name = "us-lb",
      algorithm = "round_robin",
      region = "nyc3",
      forwarding_rules = [
        {
          entry_protocol = "https",
          entry_port = 443,
          target_protocol = "http",
          target_port = 8080,
          certificate_id = "cert-id"
        }
      ],
      health_check = {
        protocol = "http",
        port = 8080,
        path = "/health",
        interval = 10,
        timeout = 5,
        healthy_threshold = 3,
        unhealthy_threshold = 3
      },
      sticky_sessions = {
        type = "cookies",
        cookie_name = "REGION_SESSION",
        cookie_ttl_seconds = 300
      }
    },

    # Primary Database (Multi-AZ in DigitalOcean)
    database = digitalocean.Database & {
      name = "us-db-primary",
      engine = "pg",
      version = "14",
      size = "db-s-2vcpu-4gb",
      region = "nyc3",
      num_nodes = 3,
      multi_az = true,
      backup_retention_days = 30
    }
  },

  # =============================================================================
  # EU CENTRAL REGION (Hetzner Germany) - SECONDARY
  # =============================================================================

  region_eu_central = {
    name = "eu-central",
    provider = "hetzner",
    location = "nbg1",
    description = "Secondary region: serves Europe, read replicas",

    # Private Network
    network = hetzner.Network & {
      name = "eu-central-network",
      ip_range = "10.1.0.0/16"
    },

    # Application Servers (3 replicas for HA)
    app_servers = hetzner.Server & {
      name = "eu-app",
      server_type = "cpx21",
      image = "ubuntu-22.04",
      location = "nbg1",
      count = 3,
      networks = [
        {
          network_name = "eu-central-network",
          ip = "10.1.1.10"
        }
      ],
      labels = {
        "region" = "eu-central",
        "tier" = "application"
      }
    },

    # Load Balancer
    load_balancer = hetzner.LoadBalancer & {
      name = "eu-lb",
      load_balancer_type = "lb21",
      location = "nbg1",
      services = [
        {
          protocol = "http",
          listen_port = 443,
          destination_port = 8080,
          health_check = {
            protocol = "http",
            port = 8080,
            interval = 10,
            timeout = 5
          }
        }
      ]
    },

    # Read Replica Database (from US primary)
    database_replica = {
      type = "read-replica",
      source = "region_us_east.database",
      replication_lag_seconds = 300,
      read_only = true,
      description = "Read-only replica of US primary database"
    }
  },

  # =============================================================================
  # ASIA PACIFIC REGION (AWS Singapore) - TERTIARY
  # =============================================================================

  region_asia_southeast = {
    name = "asia-southeast",
    provider = "aws",
    region_code = "ap-southeast-1",
    description = "Tertiary region: serves Asia Pacific, read replicas",

    # VPC for region
    vpc = aws.VPC & {
      cidr_block = "10.2.0.0/16",
      enable_dns_hostnames = true,
      enable_dns_support = true,
      tags = [
        { key = "Name", value = "asia-vpc" },
        { key = "Region", value = "ap-southeast-1" }
      ]
    },

    # Private Subnet
    private_subnet = aws.Subnet & {
      vpc_id = "{{ region_asia_southeast.vpc.id }}",
      cidr_block = "10.2.1.0/24",
      availability_zone = "ap-southeast-1a",
      tags = [
        { key = "Name", value = "asia-private-subnet" }
      ]
    },

    # Application Servers (EC2 instances)
    app_servers = aws.EC2 & {
      instance_type = "t3.medium",
      image_id = "ami-xxxxxxxx",
      region = "ap-southeast-1",
      subnet_id = "{{ region_asia_southeast.private_subnet.id }}",
      count = 3,
      tags = [
        { key = "Name", value = "asia-app" },
        { key = "Region", value = "ap-southeast-1" }
      ]
    },

    # Load Balancer (ALB)
    load_balancer = aws.ALB & {
      name = "asia-lb",
      internal = false,
      load_balancer_type = "application",
      region = "ap-southeast-1",
      subnets = ["{{ region_asia_southeast.private_subnet.id }}"],
      tags = [
        { key = "Name", value = "asia-lb" }
      ]
    },

    # Read Replica Database (from US primary)
    database_replica = aws.RDS & {
      identifier = "asia-db-replica",
      replicate_source_db = "{{ region_us_east.database.identifier }}",
      instance_class = "db.t3.small",
      region = "ap-southeast-1",
      multi_az = true,
      tags = [
        { key = "Name", value = "asia-db-replica" }
      ]
    }
  },

  # =============================================================================
  # VPN Tunnels Between Regions
  # =============================================================================

  vpn_tunnels = {
    us_to_eu = {
      name = "us-eu-vpn",
      source_region = "us-east",
      destination_region = "eu-central",
      protocol = "ipsec",
      encryption = "aes-256",
      source_network = "10.0.0.0/16",
      destination_network = "10.1.0.0/16"
    },

    eu_to_asia = {
      name = "eu-asia-vpn",
      source_region = "eu-central",
      destination_region = "asia-southeast",
      protocol = "ipsec",
      encryption = "aes-256",
      source_network = "10.1.0.0/16",
      destination_network = "10.2.0.0/16"
    },

    asia_to_us = {
      name = "asia-us-vpn",
      source_region = "asia-southeast",
      destination_region = "us-east",
      protocol = "ipsec",
      encryption = "aes-256",
      source_network = "10.2.0.0/16",
      destination_network = "10.0.0.0/16"
    }
  },

  # =============================================================================
  # Global DNS and Load Balancing (Route53)
  # =============================================================================

  global_dns = {
    domain = "api.example.com",
    dns_provider = "route53",

    # Geographic routing policy
    geolocation_rules = [
      {
        location = "North America",
        endpoint = "us-east-lb",
        weight = 100
      },
      {
        location = "Europe",
        endpoint = "eu-central-lb",
        weight = 100
      },
      {
        location = "Asia Pacific",
        endpoint = "asia-southeast-lb",
        weight = 100
      }
    ],

    # Health checks for each region
    health_checks = [
      {
        region = "us-east",
        endpoint = "us.api.example.com",
        protocol = "HTTPS",
        port = 443,
        path = "/health",
        interval = 30,
        failure_threshold = 3
      },
      {
        region = "eu-central",
        endpoint = "eu.api.example.com",
        protocol = "HTTPS",
        port = 443,
        path = "/health",
        interval = 30,
        failure_threshold = 3
      },
      {
        region = "asia-southeast",
        endpoint = "asia.api.example.com",
        protocol = "HTTPS",
        port = 443,
        path = "/health",
        interval = 30,
        failure_threshold = 3
      }
    ],

    # Failover configuration
    failover_policy = {
      strategy = "geographic",
      primary = "us-east",
      secondary = "eu-central",
      tertiary = "asia-southeast",
      health_check_grace_period = 60
    }
  },

  # =============================================================================
  # Database Replication Configuration
  # =============================================================================

  database_replication = {
    mode = "multi-master",
    primary_region = "us-east",
    read_replicas = [
      {
        region = "eu-central",
        lag_tolerance = 300,
        read_only = true
      },
      {
        region = "asia-southeast",
        lag_tolerance = 300,
        read_only = true
      }
    ],

    replication_settings = {
      method = "logical",
      wal_level = "logical",
      max_wal_senders = 5,
      max_replication_slots = 5,
      backup_retention_days = 30
    }
  },

  # =============================================================================
  # Monitoring and Alerting
  # =============================================================================

  monitoring = {
    enabled = true,

    regional_metrics = [
      {
        region = "us-east",
        metrics = ["cpu", "memory", "disk", "network", "database_connections"]
      },
      {
        region = "eu-central",
        metrics = ["cpu", "memory", "disk", "network", "replication_lag"]
      },
      {
        region = "asia-southeast",
        metrics = ["cpu", "memory", "disk", "network", "replication_lag"]
      }
    ],

    alerts = [
      {
        name = "high-cpu",
        condition = "cpu > 80%",
        action = "scale-up",
        severity = "warning"
      },
      {
        name = "replication-lag",
        condition = "replication_lag > 600s",
        action = "alert",
        severity = "critical"
      },
      {
        name = "region-down",
        condition = "health_check_failed",
        action = "failover",
        severity = "critical"
      }
    ]
  },

  # =============================================================================
  # Backup and Disaster Recovery
  # =============================================================================

  backup_strategy = {
    frequency = "daily",
    retention_days = 30,

    backup_locations = [
      {
        region = "us-east",
        strategy = "automated",
        retention = "30 days"
      },
      {
        region = "eu-central",
        strategy = "replica-backup",
        retention = "30 days"
      },
      {
        region = "asia-southeast",
        strategy = "replica-backup",
        retention = "30 days"
      }
    ]
  },

  # =============================================================================
  # Cost Estimation
  # =============================================================================

  cost_estimate = {
    monthly_breakdown = {
      us_east = {
        droplets = "$72",  # 3 x $24
        load_balancer = "$0",
        database = "$30",
        subtotal = "$102"
      },

      eu_central = {
        servers = "$62.70",  # 3 x CPX21 @ €20.90
        load_balancer = "$10",
        subtotal = "€72.70 (~$79)"
      },

      asia_southeast = {
        ec2 = "$80",  # 3 x t3.medium
        alb = "$20",
        database = "$30",
        subtotal = "$130"
      },

      total_monthly = "$311",
      total_annual = "$3,732"
    }
  }
}
