# Per-Region Deployment Module
# Deploys all Well-Architected Framework resources for a single region

terraform {
  required_version = ">= 1.0"
}

# Resource Groups - Well-Architected Framework Structure
resource "azurerm_resource_group" "network" {
  name     = "${var.cloud_provider}-${var.env_code}-${var.region_code}-rg-net-001"
  location = var.region_name
  
  tags = merge(var.common_tags, {
    Purpose = "Networking"
    Region  = var.region_display
  })
  
  lifecycle {
    # Prevent deletion if resources exist (for admin region with existing resources)
    prevent_destroy = false
  }
}

resource "azurerm_resource_group" "compute" {
  name     = "${var.cloud_provider}-${var.env_code}-${var.region_code}-rg-comp-001"
  location = var.region_name
  
  tags = merge(var.common_tags, {
    Purpose = "Compute"
    Region  = var.region_display
  })
  
  lifecycle {
    # Prevent deletion if resources exist (for admin region with existing resources)
    prevent_destroy = false
    # Ignore changes to tags if resource group already exists
    ignore_changes = [tags]
  }
}

resource "azurerm_resource_group" "storage" {
  name     = "${var.cloud_provider}-${var.env_code}-${var.region_code}-rg-stor-001"
  location = var.region_name

  tags = merge(var.common_tags, {
    Purpose = "Storage"
    Region  = var.region_display
  })
}

resource "azurerm_resource_group" "security" {
  name     = "${var.cloud_provider}-${var.env_code}-${var.region_code}-rg-sec-001"
  location = var.region_name

  tags = merge(var.common_tags, {
    Purpose = "Security"
    Region  = var.region_display
  })
}

resource "azurerm_resource_group" "monitoring" {
  name     = "${var.cloud_provider}-${var.env_code}-${var.region_code}-rg-mon-001"
  location = var.region_name

  tags = merge(var.common_tags, {
    Purpose = "Monitoring"
    Region  = var.region_display
  })
}

resource "azurerm_resource_group" "identity" {
  name     = "${var.cloud_provider}-${var.env_code}-${var.region_code}-rg-id-001"
  location = var.region_name

  tags = merge(var.common_tags, {
    Purpose = "Identity"
    Region  = var.region_display
  })
}

# Virtual Network (simplified - create basic VNet)
resource "azurerm_virtual_network" "main" {
  name                = "${var.cloud_provider}-${var.env_code}-${var.region_code}-vnet-main"
  address_space       = ["10.0.0.0/16"]
  location            = var.region_name
  resource_group_name = azurerm_resource_group.network.name

  tags = merge(var.common_tags, {
    Purpose = "Networking"
    Region  = var.region_display
  })
}

# Subnet for AKS
resource "azurerm_subnet" "aks" {
  name                 = "${var.cloud_provider}-${var.env_code}-${var.region_code}-snet-aks"
  resource_group_name  = azurerm_resource_group.network.name
  virtual_network_name = azurerm_virtual_network.main.name
  address_prefixes     = ["10.0.1.0/24"]

  # REQUIRED: Subnet delegation for AKS (fixes BadRequest errors)
  delegation {
    name = "aks-delegation"
    service_delegation {
      name    = "Microsoft.ContainerService/managedClusters"
      actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"]
    }
  }

  # Service endpoints for AKS (improves performance and security)
  # Note: Microsoft.ContainerService is NOT a valid service endpoint - it's used in delegation only
  # Valid service endpoints: Storage, KeyVault (ContainerService is in delegation block above)
  service_endpoints = ["Microsoft.Storage", "Microsoft.KeyVault"]
}

# Subnet for nodes
resource "azurerm_subnet" "nodes" {
  name                 = "${var.cloud_provider}-${var.env_code}-${var.region_code}-snet-nodes"
  resource_group_name  = azurerm_resource_group.network.name
  virtual_network_name = azurerm_virtual_network.main.name
  address_prefixes     = ["10.0.2.0/24"]
}

# Key Vault (simplified)
# Use region-specific suffix to ensure global uniqueness
# Naming convention: az-p-{code}-kv-secrets-001 (matches Resource Group pattern)
resource "azurerm_key_vault" "main" {
  name                = "${var.cloud_provider}-${var.env_code}-${var.region_code}-kv-secrets-001"
  location            = var.region_name
  resource_group_name = azurerm_resource_group.security.name
  tenant_id           = data.azurerm_client_config.current.tenant_id
  sku_name            = "standard"

  soft_delete_retention_days = 7
  purge_protection_enabled   = false

  tags = merge(var.common_tags, {
    Purpose = "Security"
    Region  = var.region_display
  })

  # Lifecycle to handle existing vaults
  lifecycle {
    ignore_changes = [name]
  }
}

# Data source for current client config
data "azurerm_client_config" "current" {}

# Log Analytics Workspace
# Note: Some regions don't support Log Analytics - use nearest supported region
locals {
  # Map regions that don't support Log Analytics to nearest supported region
  # austriaeast - Log Analytics uses nearest supported region (westeurope)
  log_analytics_location = contains([
    "belgiumcentral", "westindia", "austriaeast"
  ], var.region_name) ? "westeurope" : var.region_name
}

resource "azurerm_log_analytics_workspace" "main" {
  name                = "${var.cloud_provider}-${var.env_code}-${var.region_code}-law-main"
  location            = local.log_analytics_location
  resource_group_name = azurerm_resource_group.monitoring.name
  sku                 = "PerGB2018"
  retention_in_days   = 90

  tags = merge(var.common_tags, {
    Purpose = "Logging"
    Region  = var.region_display
    Note    = local.log_analytics_location != var.region_name ? "Deployed to ${local.log_analytics_location} (nearest supported)" : ""
  })
}

# Storage Account for Terraform State
resource "azurerm_storage_account" "tfstate" {
  name                     = replace("${var.cloud_provider}${var.env_code}${var.region_code}tfstate001", "-", "")
  resource_group_name      = azurerm_resource_group.storage.name
  location                 = var.region_name
  account_tier             = "Standard"
  account_replication_type = "LRS"
  min_tls_version          = "TLS1_2"

  blob_properties {
    versioning_enabled = true
    delete_retention_policy {
      days = 30
    }
  }

  tags = merge(var.common_tags, {
    Purpose = "TerraformState"
    Region  = var.region_display
  })
}

# Storage Container for Terraform State
resource "azurerm_storage_container" "tfstate" {
  name                  = "tfstate"
  storage_account_name  = azurerm_storage_account.tfstate.name
  container_access_type = "private"
}

# Variables
variable "region_name" {
  description = "Azure region name (e.g., westeurope)"
  type        = string
}

variable "region_code" {
  description = "Short region code (e.g., we)"
  type        = string
}

variable "region_display" {
  description = "Display name for region"
  type        = string
}

variable "cloud_provider" {
  description = "Cloud provider code"
  type        = string
  default     = "az"
}

variable "env_code" {
  description = "Environment code"
  type        = string
  default     = "p"
}

variable "subscription_id" {
  description = "Azure subscription ID"
  type        = string
}

variable "common_tags" {
  description = "Common tags for all resources"
  type        = map(string)
}

variable "deploy_aks_clusters" {
  description = "Deploy AKS clusters"
  type        = bool
  default     = false
}

variable "validator_count" {
  description = "Number of validator nodes per region"
  type        = number
  default     = 1
}

variable "validator_vm_size" {
  description = "VM size for validator nodes"
  type        = string
  default     = "Standard_D2psv6"  # 2 vCPUs, 8 GB RAM (4 GB RAM/vCPU) - Arm-based
}

variable "sentry_count" {
  description = "Number of sentry nodes per region"
  type        = number
  default     = 0
}

# sentry_vm_size variable removed - not used (sentries deployed as pods, not VMs)
# If sentries need VMs in the future, uncomment and add to module inputs:
# variable "sentry_vm_size" {
#   description = "VM size for sentry nodes"
#   type        = string
#   default     = "Standard_B2s"
# }

# Outputs
output "resource_groups" {
  value = {
    network    = azurerm_resource_group.network.name
    compute    = azurerm_resource_group.compute.name
    storage    = azurerm_resource_group.storage.name
    security   = azurerm_resource_group.security.name
    monitoring = azurerm_resource_group.monitoring.name
    identity   = azurerm_resource_group.identity.name
  }
}

output "networks" {
  value = {
    vnet_id         = azurerm_virtual_network.main.id
    vnet_name       = azurerm_virtual_network.main.name
    aks_subnet_id   = azurerm_subnet.aks.id
    nodes_subnet_id = azurerm_subnet.nodes.id
  }
}

output "key_vaults" {
  value = {
    key_vault_id  = azurerm_key_vault.main.id
    key_vault_uri = azurerm_key_vault.main.vault_uri
  }
}
