# Define local variables for common configuration and resource naming
locals {
  
  fme_config_params = join(" ", [
    "-JobTitle \"${var.fme_job_title}\"",
    "-Company \"${var.fme_company}\"",
    "-Industry \"${var.fme_industry}\"",
    "-Email \"${var.fme_email}\"",
    "-FirstName \"${var.fme_first_name}\"",
    "-LastName \"${var.fme_last_name}\"",
    "-SerialNumber \"${var.fme_serial_number}\"",
    "-AdminUser \"${var.fme_admin_username}\"",
    "-AdminPwd \"${var.fme_admin_password}\"",
    "-NewAdminPwd \"${var.fme_new_admin_password}\"",
    "-ReverseProxyUrl \"${var.reverse_proxy_url}\"",
    "-InstallerUrl \"${var.fme_installer_url}\"", 
    "-DatabasePassword \"fmeflow\"",
    "-NonInteractive"
  ])

  # Naming Locals
  vm_name           = upper(var.base_name_prefix)
  vm_comp_name      = upper(replace(var.base_name_prefix, "-", ""))
  pip_name          = "${var.base_name_prefix}-pip"
  nsg_name          = "${var.base_name_prefix}-nsg"
  nic_name          = "${var.base_name_prefix}-nic"
  os_disk_name      = "${local.vm_name}_OsDisk"
  vm_extension_name = "${var.base_name_prefix}-customscript"
}

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">=4.1.0"
    }
  }

  # --- REMOTE BACKEND CONFIGURATION (State File Storage) ---
  backend "azurerm" {
    resource_group_name  = "EXPERTS-11130Testing"
    storage_account_name = "mgstoracctterraform"
    container_name       = "tfstate"               # Container for the state file
    key                  = "fme-flow-deployment.tfstate" # Name of the state file blob
  }
}

provider "azurerm" {
  features {}
}

# ==========================================================
# VARIABLES
# ==========================================================

# --- NEW FME INSTALLER URL VARIABLE ---
variable "fme_installer_url" {
  type        = string
  description = "The URL for the FME Flow Windows installer EXE file (e.g., https://downloads.safe.com/...)."
}
# ------------------------------------

# --- NEW NAMING AND CONFIGURATION VARIABLES ---
variable "base_name_prefix" {
  type        = string
  description = "A short, unique prefix (e.g., 'fme-staging-001') used to name all resources. This value must be unique."
}

variable "vm_admin_username" {
  type        = string
  description = "The administrator username for the Azure Windows VM host."
}

variable "resource_owner" {
  type        = string
  description = "The tag value for the 'Owner' field."
}

variable "project_name" {
  type        = string
  description = "The tag value for the 'Project' field."
}

variable "storage_account_uri" {
  type        = string
  description = "The base URL for the Azure Storage Container hosting the installation scripts (e.g., mystorage.blob.core.windows.net/myscripts)."
}

variable "sas_token" {
  type        = string
  description = "The SAS Token for accessing the scripts in the storage container. **Must be secure/sensitive.**"
  sensitive   = true # Mark as sensitive for security
}
# ----------------------------

variable "vm_admin_password" {
  type        = string
  description = "The password for the Azure Windows VM."
  sensitive   = true
}

variable "resource_group_name" {
  type = string
}

variable "location" {
  type  = string
}

variable "app_gateway_name" {
  type = string
}

variable "backend_pool_name" {
  type = string
}

# --- EXISTING NETWORK VARIABLES ---
variable "virtual_network_name" {
  type        = string
  description = "The name of the pre-existing Virtual Network."
}

variable "subnet_name" {
  type        = string
  description = "The name of the pre-existing Subnet."
}
# ----------------------------

variable "fme_admin_username" {
  type    = string
  default = "admin"
}

variable "fme_admin_password" {
  type      = string
  sensitive = true
}

variable "fme_new_admin_password" {
  type      = string
  sensitive = true
}

variable "reverse_proxy_url" {
  type = string
}

# FME FLOW LICENSING/IDENTITY
variable "fme_job_title" {
  type  = string
}

variable "fme_company" {
  type  = string
}

variable "fme_industry" {
  type  = string
}

variable "fme_email" {
  type  = string
}

variable "fme_first_name" {
  type  = string
}

variable "fme_last_name" {
  type  = string
}

variable "fme_serial_number" {
  type        = string
  description = "The FME Flow license serial number."
}


# ==========================================================
# NETWORKING AND INFRASTRUCTURE
# ==========================================================
data "azurerm_subnet" "subnet" {
  name                 = var.subnet_name
  virtual_network_name = var.virtual_network_name
  resource_group_name  = var.resource_group_name
}

resource "azurerm_public_ip" "vm_pip" {
  name                = local.pip_name
  location            = var.location
  resource_group_name = var.resource_group_name
  allocation_method   = "Static"
  sku                 = "Standard"
}

resource "azurerm_network_security_group" "vm_nsg" {
  name                = local.nsg_name
  location            = var.location
  resource_group_name = var.resource_group_name

  security_rule {
    name                         = "Allow-RDP"
    priority                     = 1000
    direction                    = "Inbound"
    access                       = "Allow"
    protocol                     = "Tcp"
    destination_port_range       = "3389"
    source_port_range            = "*"
    source_address_prefix        = "*"
    destination_address_prefix   = "*"
  }

  security_rule {
    name                         = "Allow-HTTP"
    priority                     = 1001
    direction                    = "Inbound"
    access                       = "Allow"
    protocol                     = "Tcp"
    destination_port_range       = "80"
    source_port_range            = "*"
    source_address_prefix        = "*"
    destination_address_prefix   = "*"
  }

  security_rule {
    name                         = "Allow-HTTPS"
    priority                     = 1002
    direction                    = "Inbound"
    access                       = "Allow"
    protocol                     = "Tcp"
    destination_port_range       = "443"
    source_port_range            = "*"
    source_address_prefix        = "*"
    destination_address_prefix   = "*"
  }

  security_rule {
    name                         = "Allow-HTTP-Outbound"
    priority                     = 2000
    direction                    = "Outbound"
    access                       = "Allow"
    protocol                     = "Tcp"
    destination_port_range       = "80"
    source_port_range            = "*"
    source_address_prefix        = "*"
    destination_address_prefix   = "*"
  }

  security_rule {
    name                         = "Allow-HTTPS-Outbound"
    priority                     = 2001
    direction                    = "Outbound"
    access                       = "Allow"
    protocol                     = "Tcp"
    destination_port_range       = "443"
    source_port_range            = "*"
    source_address_prefix        = "*"
    destination_address_prefix   = "*"
  }
}

resource "azurerm_network_interface" "vm_nic" {
  name                = local.nic_name
  location            = var.location
  resource_group_name = var.resource_group_name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = data.azurerm_subnet.subnet.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.vm_pip.id
  }
}

resource "azurerm_network_interface_security_group_association" "vm_nic_nsg" {
  network_interface_id        = azurerm_network_interface.vm_nic.id
  network_security_group_id = azurerm_network_security_group.vm_nsg.id
}

# ==========================================================
# WINDOWS VM
# ==========================================================
resource "azurerm_windows_virtual_machine" "vm" {
  name                = local.vm_name
  computer_name       = local.vm_comp_name
  location            = var.location
  resource_group_name = var.resource_group_name
  size                = "Standard_D4s_v3"
  admin_username      = var.vm_admin_username
  admin_password      = var.vm_admin_password
  zone                = "1"

  network_interface_ids = [azurerm_network_interface.vm_nic.id]

  os_disk {
    name                 = local.os_disk_name
    caching              = "ReadWrite"
    storage_account_type = "Premium_LRS"
    disk_size_gb         = 127
  }

  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2022-datacenter-g2"
    version   = "latest"
  }

  secure_boot_enabled       = true
  vtpm_enabled              = true
  patch_mode                = "AutomaticByOS"
  provision_vm_agent        = true
  automatic_updates_enabled = true

  boot_diagnostics {}

  tags = {
    Owner   = var.resource_owner
    Project = var.project_name
  }
}

# ==========================================================
# APP GATEWAY BACKEND UPDATE
# ==========================================================
resource "null_resource" "add_to_backend_pool" {
  depends_on = [azurerm_windows_virtual_machine.vm]

  provisioner "local-exec" {
    when        = create
    command     = <<EOT
IP=$(az network nic show --ids ${azurerm_network_interface.vm_nic.id} --query "ipConfigurations[0].privateIPAddress" -o tsv)

az network application-gateway address-pool update \
  --gateway-name ${var.app_gateway_name} \
  --resource-group ${var.resource_group_name} \
  --name ${var.backend_pool_name} \
  --add backendAddresses "{\"ipAddress\":\"$IP\"}"
EOT
    interpreter = ["/bin/bash", "-c"]
  }
}

# ==========================================================
# INSTALL + CONFIGURE 
# ==========================================================
resource "azurerm_virtual_machine_extension" "fmeflow_customscript" {
  name                = local.vm_extension_name
  virtual_machine_id  = azurerm_windows_virtual_machine.vm.id
  publisher           = "Microsoft.Compute"
  type                = "CustomScriptExtension"
  type_handler_version = "1.10"
  depends_on          = [null_resource.add_to_backend_pool]

  settings = jsonencode({
    fileUris = [
      "https://${var.storage_account_uri}/fme-flow-deploy.ps1?${var.sas_token}"
    ]
    # Executes the single script with all arguments
    commandToExecute = "powershell -ExecutionPolicy Bypass -File fme-flow-deploy.ps1 ${local.fme_config_params}"
  })

  timeouts {
    create = "90m"
    update = "90m"
  }
}

# ==========================================================
# OUTPUTS
# ==========================================================
output "vm_public_ip" {
  description = "Public IP address of the VM"
  value       = azurerm_public_ip.vm_pip.ip_address
}

output "fmeflow_health_url" {
  description = "Health check URL for the deployed FME Flow instance"
  value       = "http://${azurerm_public_ip.vm_pip.ip_address}/fmeapiv4/healthcheck/liveness?includeDetails=false"
}