# Complete Application Gateway Configuration
# This file provides a complete Application Gateway setup with backend pools, listeners, and routing rules
# Note: This requires AKS service IPs to be known. For dynamic configuration, use AGIC (Application Gateway Ingress Controller)

# Backend Address Pool for RPC nodes
resource "azurerm_application_gateway_backend_address_pool" "rpc" {
  name                = "${var.cluster_name}-rpc-backend-pool"
  resource_group_name = var.resource_group_name
  application_gateway_name = azurerm_application_gateway.main.name
  
  # IP addresses will be populated after AKS deployment
  # Use data source or variables to get service IPs
  # fqdns = [var.rpc_service_fqdn]
  # ip_addresses = var.rpc_service_ips
}

# Backend Address Pool for Blockscout
resource "azurerm_application_gateway_backend_address_pool" "blockscout" {
  name                = "${var.cluster_name}-blockscout-backend-pool"
  resource_group_name = var.resource_group_name
  application_gateway_name = azurerm_application_gateway.main.name
}

# HTTP Settings for RPC
resource "azurerm_application_gateway_backend_http_settings" "rpc" {
  name                                = "${var.cluster_name}-rpc-http-settings"
  resource_group_name                 = var.resource_group_name
  application_gateway_name            = azurerm_application_gateway.main.name
  port                                = 8545
  protocol                            = "Http"
  cookie_based_affinity               = "Disabled"
  request_timeout                     = 60
  probe_name                          = azurerm_application_gateway_probe.rpc.name
  pick_host_name_from_backend_address = false
}

# HTTP Settings for Blockscout
resource "azurerm_application_gateway_backend_http_settings" "blockscout" {
  name                                = "${var.cluster_name}-blockscout-http-settings"
  resource_group_name                 = var.resource_group_name
  application_gateway_name            = azurerm_application_gateway.main.name
  port                                = 4000
  protocol                            = "Http"
  cookie_based_affinity               = "Disabled"
  request_timeout                     = 60
  probe_name                          = azurerm_application_gateway_probe.blockscout.name
  pick_host_name_from_backend_address = false
}

# Health Probe for RPC
resource "azurerm_application_gateway_probe" "rpc" {
  name                = "${var.cluster_name}-rpc-probe"
  resource_group_name = var.resource_group_name
  application_gateway_name = azurerm_application_gateway.main.name
  
  protocol            = "Http"
  path                = "/"
  host                = "127.0.0.1"
  interval            = 30
  timeout             = 30
  unhealthy_threshold = 3
  minimum_servers     = 1
  
  match {
    status_code = ["200-399"]
  }
}

# Health Probe for Blockscout
resource "azurerm_application_gateway_probe" "blockscout" {
  name                = "${var.cluster_name}-blockscout-probe"
  resource_group_name = var.resource_group_name
  application_gateway_name = azurerm_application_gateway.main.name
  
  protocol            = "Http"
  path                = "/"
  host                = "127.0.0.1"
  interval            = 30
  timeout             = 30
  unhealthy_threshold = 3
  minimum_servers     = 1
  
  match {
    status_code = ["200-399"]
  }
}

# HTTP Listener for RPC (HTTP)
resource "azurerm_application_gateway_http_listener" "rpc_http" {
  name                           = "${var.cluster_name}-rpc-http-listener"
  resource_group_name            = var.resource_group_name
  application_gateway_name       = azurerm_application_gateway.main.name
  frontend_ip_configuration_name = "appGatewayFrontendIP"
  frontend_port_name             = "http"
  protocol                       = "Http"
  host_name                      = var.rpc_hostname
}

# HTTPS Listener for RPC (HTTPS)
resource "azurerm_application_gateway_http_listener" "rpc_https" {
  name                           = "${var.cluster_name}-rpc-https-listener"
  resource_group_name            = var.resource_group_name
  application_gateway_name       = azurerm_application_gateway.main.name
  frontend_ip_configuration_name = "appGatewayFrontendIP"
  frontend_port_name             = "https"
  protocol                       = "Https"
  ssl_certificate_name           = azurerm_application_gateway_ssl_certificate.rpc.name
  host_name                      = var.rpc_hostname
}

# HTTP Listener for Blockscout (HTTP)
resource "azurerm_application_gateway_http_listener" "blockscout_http" {
  name                           = "${var.cluster_name}-blockscout-http-listener"
  resource_group_name            = var.resource_group_name
  application_gateway_name       = azurerm_application_gateway.main.name
  frontend_ip_configuration_name = "appGatewayFrontendIP"
  frontend_port_name             = "http"
  protocol                       = "Http"
  host_name                      = var.blockscout_hostname
}

# HTTPS Listener for Blockscout (HTTPS)
resource "azurerm_application_gateway_http_listener" "blockscout_https" {
  name                           = "${var.cluster_name}-blockscout-https-listener"
  resource_group_name            = var.resource_group_name
  application_gateway_name        = azurerm_application_gateway.main.name
  frontend_ip_configuration_name = "appGatewayFrontendIP"
  frontend_port_name             = "https"
  protocol                       = "Https"
  ssl_certificate_name           = azurerm_application_gateway_ssl_certificate.blockscout.name
  host_name                      = var.blockscout_hostname
}

# SSL Certificate for RPC (use Azure Key Vault or upload certificate)
resource "azurerm_application_gateway_ssl_certificate" "rpc" {
  name                = "${var.cluster_name}-rpc-ssl-cert"
  resource_group_name = var.resource_group_name
  application_gateway_name = azurerm_application_gateway.main.name
  
  # Option 1: Use Key Vault certificate
  # key_vault_secret_id = var.rpc_ssl_certificate_key_vault_secret_id
  
  # Option 2: Upload certificate data (not recommended for production)
  # data = var.rpc_ssl_certificate_data
  # password = var.rpc_ssl_certificate_password
}

# SSL Certificate for Blockscout
resource "azurerm_application_gateway_ssl_certificate" "blockscout" {
  name                = "${var.cluster_name}-blockscout-ssl-cert"
  resource_group_name = var.resource_group_name
  application_gateway_name = azurerm_application_gateway.main.name
  
  # Option 1: Use Key Vault certificate
  # key_vault_secret_id = var.blockscout_ssl_certificate_key_vault_secret_id
  
  # Option 2: Upload certificate data
  # data = var.blockscout_ssl_certificate_data
  # password = var.blockscout_ssl_certificate_password
}

# Request Routing Rule for RPC HTTP
resource "azurerm_application_gateway_request_routing_rule" "rpc_http" {
  name                       = "${var.cluster_name}-rpc-http-rule"
  resource_group_name        = var.resource_group_name
  application_gateway_name   = azurerm_application_gateway.main.name
  rule_type                  = "Basic"
  http_listener_name         = azurerm_application_gateway_http_listener.rpc_http.name
  backend_address_pool_name  = azurerm_application_gateway_backend_address_pool.rpc.name
  backend_http_settings_name = azurerm_application_gateway_backend_http_settings.rpc.name
}

# Request Routing Rule for RPC HTTPS
resource "azurerm_application_gateway_request_routing_rule" "rpc_https" {
  name                       = "${var.cluster_name}-rpc-https-rule"
  resource_group_name        = var.resource_group_name
  application_gateway_name   = azurerm_application_gateway.main.name
  rule_type                  = "Basic"
  http_listener_name         = azurerm_application_gateway_http_listener.rpc_https.name
  backend_address_pool_name  = azurerm_application_gateway_backend_address_pool.rpc.name
  backend_http_settings_name = azurerm_application_gateway_backend_http_settings.rpc.name
}

# Request Routing Rule for Blockscout HTTP
resource "azurerm_application_gateway_request_routing_rule" "blockscout_http" {
  name                       = "${var.cluster_name}-blockscout-http-rule"
  resource_group_name        = var.resource_group_name
  application_gateway_name   = azurerm_application_gateway.main.name
  rule_type                  = "Basic"
  http_listener_name         = azurerm_application_gateway_http_listener.blockscout_http.name
  backend_address_pool_name  = azurerm_application_gateway_backend_address_pool.blockscout.name
  backend_http_settings_name = azurerm_application_gateway_backend_http_settings.blockscout.name
}

# Request Routing Rule for Blockscout HTTPS
resource "azurerm_application_gateway_request_routing_rule" "blockscout_https" {
  name                       = "${var.cluster_name}-blockscout-https-rule"
  resource_group_name        = var.resource_group_name
  application_gateway_name   = azurerm_application_gateway.main.name
  rule_type                  = "Basic"
  http_listener_name         = azurerm_application_gateway_http_listener.blockscout_https.name
  backend_address_pool_name  = azurerm_application_gateway_backend_address_pool.blockscout.name
  backend_http_settings_name = azurerm_application_gateway_backend_http_settings.blockscout.name
}

# Redirect HTTP to HTTPS for RPC
resource "azurerm_application_gateway_redirect_configuration" "rpc_http_redirect" {
  name                = "${var.cluster_name}-rpc-http-redirect"
  resource_group_name = var.resource_group_name
  application_gateway_name = azurerm_application_gateway.main.name
  
  redirect_type = "Permanent"
  target_listener_name = azurerm_application_gateway_http_listener.rpc_https.name
  include_path = true
  include_query_string = true
}

# Redirect HTTP to HTTPS for Blockscout
resource "azurerm_application_gateway_redirect_configuration" "blockscout_http_redirect" {
  name                = "${var.cluster_name}-blockscout-http-redirect"
  resource_group_name = var.resource_group_name
  application_gateway_name = azurerm_application_gateway.main.name
  
  redirect_type = "Permanent"
  target_listener_name = azurerm_application_gateway_http_listener.blockscout_https.name
  include_path = true
  include_query_string = true
}
