locals {
  secrets_env = <<-EOT
    MYSQL_ROOT_PASSWORD=${local.mysql_root_password}
    MYSQL_USER=${var.mysql_user}
    MYSQL_PASSWORD=${local.mysql_password}
    KAFKA_SASL_USERNAME=${local.kafka_sasl_username}
    KAFKA_SASL_PASSWORD=${local.kafka_sasl_password}
    PULSAR_PROXY_TOKEN=${data.external.pulsar_proxy_token.result.token}
    PULSAR_ADMIN_TOKEN=${data.external.pulsar_admin_token.result.token}
    PULSAR_CLIENT_TOKEN=${data.external.pulsar_client_token.result.token}
    SCHEMA_REGISTRY_USERNAME=${local.schema_registry_username}
    SCHEMA_REGISTRY_PASSWORD=${local.schema_registry_password}
  EOT

  compose_yaml = templatefile("${path.module}/../../templates/compose.yaml.tftpl", {
    mysql_image                       = local.images.mysql
    kafka_image                       = local.images.kafka
    pulsar_image                      = local.images.pulsar
    kafka_proxy_image                 = local.images.kafka_proxy
    schema_registry_image             = local.images.schema_registry
    mysql_port                        = local.ports.mysql
    kafka_public_port                 = local.ports.kafka_public
    kafka_sasl_port                   = local.ports.kafka_sasl
    kafka_pl_public_port              = local.ports.kafka_pl_public
    kafka_pl_sasl_port                = local.ports.kafka_pl_sasl
    pulsar_binary_port                = local.ports.pulsar_binary
    pulsar_admin_http_port            = local.ports.pulsar_admin_http
    schema_registry_port              = local.ports.schema_registry
    public_ip                         = azurerm_public_ip.services.ip_address
    kafka_privatelink_advertised_host = local.kafka_privatelink_advertised_host
    kafka_cluster_id                  = local.kafka_cluster_id
    enable_pulsar                     = var.enable_pulsar
    enable_schema_registry            = var.enable_schema_registry
  })
  mysql_config = templatefile("${path.module}/../../templates/mysql.cnf.tftpl", {})
  mysql_init = templatefile("${path.module}/../../templates/mysql-init.sql.tftpl", {
    mysql_user = var.mysql_user
  })
  service_unit = templatefile("${path.module}/../../templates/date-integration.service.tftpl", {})
  seed_script = templatefile("${path.module}/../../templates/seed-services.sh.tftpl", {
    mysql_user             = var.mysql_user
    pulsar_binary_port     = local.ports.pulsar_binary
    pulsar_admin_http_port = local.ports.pulsar_admin_http
    schema_registry_port   = local.ports.schema_registry
    enable_pulsar          = var.enable_pulsar
    enable_schema_registry = var.enable_schema_registry
  })
  schema_registry_jaas  = <<-EOT
    SchemaRegistry-Props {
      org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required
      file="/etc/schema-registry/schema-registry-users.properties";
    };
  EOT
  schema_registry_users = "${local.schema_registry_username}: MD5:${md5(local.schema_registry_password)},user\n"
  install_services = templatefile("${path.module}/../../templates/install-services.sh.tftpl", {
    compose_b64               = base64encode(local.compose_yaml)
    mysql_config_b64          = base64encode(local.mysql_config)
    mysql_init_b64            = base64encode(local.mysql_init)
    pulsar_secret_b64         = local.pulsar_token_secret
    secrets_env_b64           = base64encode(local.secrets_env)
    service_unit_b64          = base64encode(local.service_unit)
    seed_script_b64           = base64encode(local.seed_script)
    schema_registry_jaas_b64  = base64encode(local.schema_registry_jaas)
    schema_registry_users_b64 = base64encode(local.schema_registry_users)
    mysql_credentials_hash    = sha256("${local.mysql_root_password}:${local.mysql_password}")
    pulsar_credentials_hash   = sha256("${local.pulsar_token_secret}:stable-network-v1")
  })
  user_data = templatefile("${path.module}/../../templates/user-data-linux.sh.tftpl", {
    data_device_path     = "/dev/disk/azure/scsi1/lun0"
    compose_version      = "v2.39.4"
    compose_sha256_amd64 = "7af95166a730b87e172d4fc9aefea8725d3c6c7327d59149267b452114ddb7d4"
    compose_sha256_arm64 = "49082844b87f03cdcd5f5bbef1ba8c9c897b7a2dfb80cea18d61ec8ca6117e0c"
    install_services_b64 = base64encode(local.install_services)
  })
}

resource "azurerm_linux_virtual_machine" "services" {
  name                            = "${local.deployment_name}-services"
  computer_name                   = "date-integration"
  location                        = azurerm_resource_group.this.location
  resource_group_name             = azurerm_resource_group.this.name
  size                            = var.vm_size
  admin_username                  = "azureuser"
  admin_password                  = random_password.admin.result
  disable_password_authentication = false
  network_interface_ids           = [azurerm_network_interface.services.id]
  custom_data                     = base64encode(local.user_data)
  tags                            = local.tags

  os_disk {
    name                 = "${local.deployment_name}-os"
    caching              = "ReadWrite"
    storage_account_type = "Premium_LRS"
    disk_size_gb         = var.root_disk_size_gib
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts-arm64"
    version   = "latest"
  }
}

resource "azurerm_managed_disk" "data" {
  name                 = "${local.deployment_name}-data"
  location             = azurerm_resource_group.this.location
  resource_group_name  = azurerm_resource_group.this.name
  storage_account_type = "Premium_LRS"
  create_option        = "Empty"
  disk_size_gb         = var.data_disk_size_gib
  tags                 = local.tags
}

resource "azurerm_virtual_machine_data_disk_attachment" "data" {
  managed_disk_id    = azurerm_managed_disk.data.id
  virtual_machine_id = azurerm_linux_virtual_machine.services.id
  lun                = 0
  caching            = "ReadWrite"
}

resource "terraform_data" "wait_for_initial_bootstrap" {
  triggers_replace = [azurerm_linux_virtual_machine.services.id]

  provisioner "local-exec" {
    command     = "${path.module}/../../scripts/wait-for-azure-bootstrap.sh"
    interpreter = ["/usr/bin/env", "bash", "-c"]
    environment = {
      AZURE_SUBSCRIPTION_ID = var.azure_subscription_id
      VM_ID                 = azurerm_linux_virtual_machine.services.id
      BOOTSTRAP_TIMEOUT     = "1800"
    }
  }

  depends_on = [azurerm_virtual_machine_data_disk_attachment.data]
}

resource "terraform_data" "instance_state" {
  triggers_replace = [var.desired_state, azurerm_linux_virtual_machine.services.id]

  provisioner "local-exec" {
    command = (
      var.desired_state == "running"
      ? "az vm start --ids '${azurerm_linux_virtual_machine.services.id}' --subscription '${var.azure_subscription_id}' --only-show-errors"
      : "az vm deallocate --ids '${azurerm_linux_virtual_machine.services.id}' --subscription '${var.azure_subscription_id}' --only-show-errors"
    )
    interpreter = ["/usr/bin/env", "bash", "-c"]
  }

  depends_on = [terraform_data.wait_for_initial_bootstrap]
}

resource "terraform_data" "wait_after_state_change" {
  triggers_replace = [var.desired_state, azurerm_linux_virtual_machine.services.id]

  provisioner "local-exec" {
    command     = var.desired_state == "running" ? "${path.module}/../../scripts/wait-for-azure-bootstrap.sh" : "true"
    interpreter = ["/usr/bin/env", "bash", "-c"]
    environment = {
      AZURE_SUBSCRIPTION_ID = var.azure_subscription_id
      VM_ID                 = azurerm_linux_virtual_machine.services.id
      BOOTSTRAP_TIMEOUT     = "1800"
    }
  }

  depends_on = [terraform_data.instance_state]
}
