data "alicloud_images" "services" {
  owners        = "system"
  name_regex    = var.image_name_regex
  architecture  = "x86_64"
  os_type       = "linux"
  instance_type = var.instance_type
  most_recent   = true
}

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                         = alicloud_eip_address.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"
  data_device_serial    = replace(trimprefix(alicloud_ecs_disk.data.id, "d-"), "-", "")
  data_device_path      = "/dev/disk/by-id/nvme-Alibaba_Cloud_Elastic_Block_Storage_${local.data_device_serial}"
  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     = local.data_device_path
    compose_version      = "v2.39.4"
    compose_sha256_amd64 = "7af95166a730b87e172d4fc9aefea8725d3c6c7327d59149267b452114ddb7d4"
    compose_sha256_arm64 = "49082844b87f03cdcd5f5bbef1ba8c9c897b7a2dfb80cea18d61ec8ca6117e0c"
    install_services_b64 = base64encode(local.install_services)
  })
}

resource "terraform_data" "bootstrap_revision" {
  input = sha256(local.user_data)
}

resource "alicloud_instance" "services" {
  instance_name                 = "${local.deployment_name}-services"
  host_name                     = "date-integration"
  image_id                      = data.alicloud_images.services.images[0].id
  instance_type                 = var.instance_type
  instance_charge_type          = "PostPaid"
  status                        = title(var.desired_state)
  stopped_mode                  = var.desired_state == "stopped" ? "StopCharging" : "Not-applicable"
  vswitch_id                    = alicloud_vswitch.services[local.service_vswitch_index].id
  security_groups               = [alicloud_security_group.services.id]
  internet_charge_type          = "PayByTraffic"
  internet_max_bandwidth_out    = 0
  system_disk_category          = "cloud_essd"
  system_disk_performance_level = "PL0"
  system_disk_size              = var.root_disk_size_gib
  system_disk_encrypted         = true
  system_disk_name              = "${local.deployment_name}-os"
  user_data                     = base64encode(local.user_data)
  deletion_protection           = false
  security_enhancement_strategy = "Active"
  tags                          = local.tags
  volume_tags                   = local.tags

  lifecycle {
    replace_triggered_by = [terraform_data.bootstrap_revision]

    precondition {
      condition     = length(data.alicloud_images.services.images) > 0
      error_message = "No compatible Ubuntu image was found for the selected ECS instance type."
    }
  }
}

resource "alicloud_ecs_disk" "data" {
  disk_name            = "${local.deployment_name}-data"
  zone_id              = alicloud_vswitch.services[local.service_vswitch_index].zone_id
  category             = "cloud_essd"
  performance_level    = "PL0"
  size                 = var.data_disk_size_gib
  encrypted            = true
  delete_with_instance = false
  tags                 = local.tags
}

resource "alicloud_ecs_disk_attachment" "data" {
  disk_id              = alicloud_ecs_disk.data.id
  instance_id          = alicloud_instance.services.id
  delete_with_instance = false
}

resource "alicloud_ecs_ram_role_attachment" "services" {
  ram_role_name = alicloud_ram_role.services.role_name
  instance_id   = alicloud_instance.services.id

  depends_on = [alicloud_ram_role_policy_attachment.oss]
}
