// VPN #2 active-active BGP migration for the existing Azure cell.
// Stage 1 (deployBgpConnections=false) adds the second public IP and converts
// the existing VpnGw1AZ gateway to active-active BGP with four custom APIPA
// addresses. Stage 2 supplies the AWS-generated endpoints and protected PSKs
// and creates four BGP-enabled connection resources. Existing static VPN #2
// connections remain untouched until the new topology passes acceptance.

param location string = 'eastasia'
param namePrefix string = 'eg334s-team2'
param vnetName string = '${namePrefix}-vnet'
param primaryGatewayPublicIpName string = '${namePrefix}-vpngw-pip'
param secondaryGatewayPublicIpName string = '${namePrefix}-vpngw-pip2'
param azureBgpAsn int = 65515
param awsBgpAsn int = 64512
param deployBgpConnections bool = false

param primaryTunnel1OutsideIp string = ''
param primaryTunnel2OutsideIp string = ''
param secondaryTunnel1OutsideIp string = ''
param secondaryTunnel2OutsideIp string = ''

@secure()
param primaryTunnel1SharedKey string = ''
@secure()
param primaryTunnel2SharedKey string = ''
@secure()
param secondaryTunnel1SharedKey string = ''
@secure()
param secondaryTunnel2SharedKey string = ''

var gatewayName = '${namePrefix}-vpngw'
var primaryIpConfigName = 'vnetGatewayConfig'
var secondaryIpConfigName = 'vnetGatewayConfig2'
var primaryIpConfigId = resourceId('Microsoft.Network/virtualNetworkGateways/ipConfigurations', gatewayName, primaryIpConfigName)
var secondaryIpConfigId = resourceId('Microsoft.Network/virtualNetworkGateways/ipConfigurations', gatewayName, secondaryIpConfigName)

var primaryTunnel1AzureBgpIp = '169.254.21.2'
var primaryTunnel1AwsBgpIp = '169.254.21.1'
var primaryTunnel2AzureBgpIp = '169.254.22.2'
var primaryTunnel2AwsBgpIp = '169.254.22.1'
var secondaryTunnel1AzureBgpIp = '169.254.21.6'
var secondaryTunnel1AwsBgpIp = '169.254.21.5'
var secondaryTunnel2AzureBgpIp = '169.254.22.6'
var secondaryTunnel2AwsBgpIp = '169.254.22.5'

// Explicitly match the hardened AWS tunnel proposals. Azure's provider
// defaults are intentionally not relied on for cross-cloud negotiation.
var strongIpsecPolicies = [
  {
    dhGroup: 'DHGroup14'
    ikeEncryption: 'AES256'
    ikeIntegrity: 'SHA256'
    ipsecEncryption: 'AES256'
    ipsecIntegrity: 'SHA256'
    pfsGroup: 'PFS14'
    saLifeTimeSeconds: 3600
    saDataSizeKilobytes: 102400000
  }
]

resource vnet 'Microsoft.Network/virtualNetworks@2023-11-01' existing = {
  name: vnetName
}

resource primaryGatewayPublicIp 'Microsoft.Network/publicIPAddresses@2023-11-01' existing = {
  name: primaryGatewayPublicIpName
}

resource secondaryGatewayPublicIp 'Microsoft.Network/publicIPAddresses@2023-11-01' = {
  name: secondaryGatewayPublicIpName
  location: location
  zones: [
    '1'
    '2'
    '3'
  ]
  tags: {
    Project: 'EG334S'
    Deployment: namePrefix
    Purpose: 'VPN2-BGP-ACTIVE-ACTIVE'
  }
  sku: {
    name: 'Standard'
  }
  properties: {
    publicIPAllocationMethod: 'Static'
  }
}

resource vpnGateway 'Microsoft.Network/virtualNetworkGateways@2023-11-01' = {
  name: gatewayName
  location: location
  tags: {
    Project: 'EG334S'
    Deployment: namePrefix
    RoutingMode: 'Dynamic-BGP'
  }
  properties: {
    activeActive: true
    enableBgp: true
    enablePrivateIpAddress: false
    gatewayType: 'Vpn'
    vpnType: 'RouteBased'
    vpnGatewayGeneration: 'Generation1'
    bgpSettings: {
      asn: azureBgpAsn
      peerWeight: 0
      bgpPeeringAddresses: [
        {
          ipconfigurationId: primaryIpConfigId
          customBgpIpAddresses: [
            primaryTunnel1AzureBgpIp
            primaryTunnel2AzureBgpIp
          ]
        }
        {
          ipconfigurationId: secondaryIpConfigId
          customBgpIpAddresses: [
            secondaryTunnel1AzureBgpIp
            secondaryTunnel2AzureBgpIp
          ]
        }
      ]
    }
    ipConfigurations: [
      {
        name: primaryIpConfigName
        properties: {
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: { id: primaryGatewayPublicIp.id }
          subnet: {
            id: resourceId('Microsoft.Network/virtualNetworks/subnets', vnet.name, 'GatewaySubnet')
          }
        }
      }
      {
        name: secondaryIpConfigName
        properties: {
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: { id: secondaryGatewayPublicIp.id }
          subnet: {
            id: resourceId('Microsoft.Network/virtualNetworks/subnets', vnet.name, 'GatewaySubnet')
          }
        }
      }
    ]
    sku: {
      name: 'VpnGw1AZ'
      tier: 'VpnGw1AZ'
    }
  }
}

resource primaryTunnel1Lng 'Microsoft.Network/localNetworkGateways@2023-11-01' = if (deployBgpConnections) {
  name: '${namePrefix}-aws-bgp-primary-t1-lng'
  location: location
  tags: { Project: 'EG334S', Deployment: namePrefix, Connection: 'VPN2-BGP-PRIMARY-T1' }
  properties: {
    gatewayIpAddress: primaryTunnel1OutsideIp
    localNetworkAddressSpace: { addressPrefixes: [] }
    bgpSettings: {
      asn: awsBgpAsn
      bgpPeeringAddress: primaryTunnel1AwsBgpIp
      peerWeight: 0
    }
  }
}

resource primaryTunnel2Lng 'Microsoft.Network/localNetworkGateways@2023-11-01' = if (deployBgpConnections) {
  name: '${namePrefix}-aws-bgp-primary-t2-lng'
  location: location
  tags: { Project: 'EG334S', Deployment: namePrefix, Connection: 'VPN2-BGP-PRIMARY-T2' }
  properties: {
    gatewayIpAddress: primaryTunnel2OutsideIp
    localNetworkAddressSpace: { addressPrefixes: [] }
    bgpSettings: {
      asn: awsBgpAsn
      bgpPeeringAddress: primaryTunnel2AwsBgpIp
      peerWeight: 0
    }
  }
}

resource secondaryTunnel1Lng 'Microsoft.Network/localNetworkGateways@2023-11-01' = if (deployBgpConnections) {
  name: '${namePrefix}-aws-bgp-secondary-t1-lng'
  location: location
  tags: { Project: 'EG334S', Deployment: namePrefix, Connection: 'VPN2-BGP-SECONDARY-T1' }
  properties: {
    gatewayIpAddress: secondaryTunnel1OutsideIp
    localNetworkAddressSpace: { addressPrefixes: [] }
    bgpSettings: {
      asn: awsBgpAsn
      bgpPeeringAddress: secondaryTunnel1AwsBgpIp
      peerWeight: 0
    }
  }
}

resource secondaryTunnel2Lng 'Microsoft.Network/localNetworkGateways@2023-11-01' = if (deployBgpConnections) {
  name: '${namePrefix}-aws-bgp-secondary-t2-lng'
  location: location
  tags: { Project: 'EG334S', Deployment: namePrefix, Connection: 'VPN2-BGP-SECONDARY-T2' }
  properties: {
    gatewayIpAddress: secondaryTunnel2OutsideIp
    localNetworkAddressSpace: { addressPrefixes: [] }
    bgpSettings: {
      asn: awsBgpAsn
      bgpPeeringAddress: secondaryTunnel2AwsBgpIp
      peerWeight: 0
    }
  }
}

resource primaryTunnel1Connection 'Microsoft.Network/connections@2023-11-01' = if (deployBgpConnections) {
  name: '${namePrefix}-vpn2-bgp-primary-t1'
  location: location
  tags: { Project: 'EG334S', Deployment: namePrefix, Connection: 'VPN2-BGP-PRIMARY-T1' }
  properties: {
    connectionType: 'IPsec'
    connectionProtocol: 'IKEv2'
    enableBgp: true
    routingWeight: 20
    sharedKey: primaryTunnel1SharedKey
    ipsecPolicies: strongIpsecPolicies
    usePolicyBasedTrafficSelectors: false
    virtualNetworkGateway1: any({ id: vpnGateway.id })
    localNetworkGateway2: any({ id: primaryTunnel1Lng.id })
    gatewayCustomBgpIpAddresses: [
      {
        ipConfigurationId: primaryIpConfigId
        customBgpIpAddress: primaryTunnel1AzureBgpIp
      }
      {
        ipConfigurationId: secondaryIpConfigId
        customBgpIpAddress: secondaryTunnel1AzureBgpIp
      }
    ]
  }
}

resource primaryTunnel2Connection 'Microsoft.Network/connections@2023-11-01' = if (deployBgpConnections) {
  name: '${namePrefix}-vpn2-bgp-primary-t2'
  location: location
  tags: { Project: 'EG334S', Deployment: namePrefix, Connection: 'VPN2-BGP-PRIMARY-T2' }
  properties: {
    connectionType: 'IPsec'
    connectionProtocol: 'IKEv2'
    enableBgp: true
    routingWeight: 10
    sharedKey: primaryTunnel2SharedKey
    ipsecPolicies: strongIpsecPolicies
    usePolicyBasedTrafficSelectors: false
    virtualNetworkGateway1: any({ id: vpnGateway.id })
    localNetworkGateway2: any({ id: primaryTunnel2Lng.id })
    gatewayCustomBgpIpAddresses: [
      {
        ipConfigurationId: primaryIpConfigId
        customBgpIpAddress: primaryTunnel2AzureBgpIp
      }
      {
        ipConfigurationId: secondaryIpConfigId
        // Microsoft mapping: unused instance-1 selector stays on tunnel 1.
        customBgpIpAddress: secondaryTunnel1AzureBgpIp
      }
    ]
  }
}

resource secondaryTunnel1Connection 'Microsoft.Network/connections@2023-11-01' = if (deployBgpConnections) {
  name: '${namePrefix}-vpn2-bgp-secondary-t1'
  location: location
  tags: { Project: 'EG334S', Deployment: namePrefix, Connection: 'VPN2-BGP-SECONDARY-T1' }
  properties: {
    connectionType: 'IPsec'
    connectionProtocol: 'IKEv2'
    enableBgp: true
    routingWeight: 5
    sharedKey: secondaryTunnel1SharedKey
    ipsecPolicies: strongIpsecPolicies
    usePolicyBasedTrafficSelectors: false
    virtualNetworkGateway1: any({ id: vpnGateway.id })
    localNetworkGateway2: any({ id: secondaryTunnel1Lng.id })
    gatewayCustomBgpIpAddresses: [
      {
        ipConfigurationId: primaryIpConfigId
        customBgpIpAddress: primaryTunnel1AzureBgpIp
      }
      {
        ipConfigurationId: secondaryIpConfigId
        customBgpIpAddress: secondaryTunnel1AzureBgpIp
      }
    ]
  }
}

resource secondaryTunnel2Connection 'Microsoft.Network/connections@2023-11-01' = if (deployBgpConnections) {
  name: '${namePrefix}-vpn2-bgp-secondary-t2'
  location: location
  tags: { Project: 'EG334S', Deployment: namePrefix, Connection: 'VPN2-BGP-SECONDARY-T2' }
  properties: {
    connectionType: 'IPsec'
    connectionProtocol: 'IKEv2'
    enableBgp: true
    routingWeight: 0
    sharedKey: secondaryTunnel2SharedKey
    ipsecPolicies: strongIpsecPolicies
    usePolicyBasedTrafficSelectors: false
    virtualNetworkGateway1: any({ id: vpnGateway.id })
    localNetworkGateway2: any({ id: secondaryTunnel2Lng.id })
    gatewayCustomBgpIpAddresses: [
      {
        ipConfigurationId: primaryIpConfigId
        // Microsoft mapping: unused instance-0 selector stays on tunnel 1.
        customBgpIpAddress: primaryTunnel1AzureBgpIp
      }
      {
        ipConfigurationId: secondaryIpConfigId
        customBgpIpAddress: secondaryTunnel2AzureBgpIp
      }
    ]
  }
}

output vpnGatewayName string = vpnGateway.name
output primaryGatewayPublicIp string = primaryGatewayPublicIp.properties.ipAddress
output secondaryGatewayPublicIp string = secondaryGatewayPublicIp.properties.ipAddress
output activeActive bool = true
output bgpEnabled bool = true
output azureBgpAsn int = azureBgpAsn
output bgpConnectionsDeployed bool = deployBgpConnections
