locals {
  cluster_service_account_name = "cluster_service_${substr(md5(var.logical_region_name), 0, 16)}"
  config_center_account_name   = "config_center_${substr(md5(var.logical_region_name), 0, 16)}"
}

data "aws_s3_object" "region_state" {
  bucket = "autonomous-deployment-terraform-state"
  key    = "alicloud/region/${var.env}-${var.cloud_region}.json"

  provider = aws.tf_state

  lifecycle {
    postcondition {
      condition     = can(jsondecode(self.body).outputs.rds_instance_id.value)
      error_message = "can't get rds instance from region ${var.cloud_region}"
    }

    postcondition {
      condition     = can(jsondecode(self.body).outputs.rds_public_connection_string.value)
      error_message = "can't get rds public connection string"
    }

    postcondition {
      condition = alltrue([for k in [
        "rds_instance_id",
        "rds_public_connection_string",
        "kms_instance_id",
        "kms_default_key_id"
      ] : can(jsondecode(self.body).outputs[k].value)])
      error_message = "missing information from region init process"
    }
  }
}

locals {
  region_outputs               = jsondecode(data.aws_s3_object.region_state.body).outputs
  rds_instance_id              = local.region_outputs.rds_instance_id.value
  rds_public_connection_string = local.region_outputs.rds_public_connection_string.value
  kms_instance_id              = local.region_outputs.kms_instance_id.value
  kms_default_key_id           = local.region_outputs.kms_default_key_id.value
}

data "alicloud_db_instances" "rds" {
  ids = [local.rds_instance_id]

  lifecycle {
    postcondition {
      condition     = length(self.ids) == 1
      error_message = "expect exactly one rds instance, found ${length(self.ids)}"
    }
  }
}

locals {
  rds_instance = data.alicloud_db_instances.rds.instances.0
}

resource "alicloud_rds_whitelist_template" "white_list_for_k8s" {
  ip_white_list = join(",", module.ack.public_ips)
  template_name = "${local.cluster_name}-whitelist-template"
}

resource "null_resource" "alicloud_db_whitelist_template_attachment" {
  triggers = {
    regional_control_account = local.seed_account
    instance_id              = local.rds_instance_id
    template_id              = alicloud_rds_whitelist_template.white_list_for_k8s.id
    region                   = var.cloud_region
  }

  provisioner "local-exec" {
    command = <<-EOT
        aliyun rds AttachWhitelistTemplateToInstance \
            --profile ${local.seed_account} \
            --region ${self.triggers.region} \
            --InsName ${self.triggers.instance_id} \
            --TemplateId ${self.triggers.template_id}
    EOT
    when    = create
  }

  provisioner "local-exec" {
    command = <<-EOT
        aliyun rds DetachWhitelistTemplateToInstance \
            --profile ${self.triggers.regional_control_account} \
            --region ${self.triggers.region} \
            --InsName ${self.triggers.instance_id} \
            --TemplateId ${self.triggers.template_id}
    EOT
    when    = destroy
  }
}

resource "random_password" "cluster_service" {
  length           = 16
  special          = true
  min_lower        = 1
  min_upper        = 1
  min_numeric      = 1
  min_special      = 1
  override_special = "!@#$%^&*()_+-="
}

resource "random_password" "config_center" {
  length           = 16
  special          = true
  min_lower        = 1
  min_upper        = 1
  min_numeric      = 1
  min_special      = 1
  override_special = "!@#$%^&*()_+-="
}

resource "alicloud_rds_account" "cluster_service" {
  db_instance_id   = local.rds_instance_id
  account_name     = local.cluster_service_account_name
  account_password = random_password.cluster_service.result
}

resource "alicloud_rds_account" "config_center" {
  db_instance_id   = local.rds_instance_id
  account_name     = local.config_center_account_name
  account_password = random_password.config_center.result
}

resource "alicloud_kms_secret" "cluster_service" {
  depends_on  = [alicloud_rds_account.cluster_service]
  secret_name = "${var.logical_region_name}-cluster-service"
  secret_data = jsonencode({
    username = local.cluster_service_account_name
    password = random_password.cluster_service.result
  })
  version_id                    = "v1"
  description                   = "RDS password for ${var.logical_region_name}-cluster-service"
  encryption_key_id             = local.kms_default_key_id
  dkms_instance_id              = local.kms_instance_id
  force_delete_without_recovery = true
}

resource "alicloud_kms_secret" "config_center" {
  depends_on  = [alicloud_rds_account.config_center]
  secret_name = "${var.logical_region_name}-config-center"
  secret_data = jsonencode({
    username = local.config_center_account_name
    password = random_password.config_center.result
  })
  version_id                    = "v1"
  description                   = "RDS password for ${var.logical_region_name}-config-center"
  encryption_key_id             = local.kms_default_key_id
  dkms_instance_id              = local.kms_instance_id
  force_delete_without_recovery = true
}

resource "alicloud_db_database" "cluster_service" {
  instance_id    = local.rds_instance_id
  data_base_name = "${var.logical_region_name}-cluster-service"
}

resource "alicloud_db_database" "config_center" {
  instance_id    = local.rds_instance_id
  data_base_name = "${var.logical_region_name}-config-center"
}

resource "alicloud_db_account_privilege" "cluster_service" {
  instance_id  = local.rds_instance_id
  account_name = alicloud_rds_account.cluster_service.account_name
  db_names     = [alicloud_db_database.cluster_service.data_base_name]
  privilege    = "ReadWrite"
}

resource "alicloud_db_account_privilege" "config_center" {
  instance_id  = local.rds_instance_id
  account_name = alicloud_rds_account.config_center.account_name
  db_names     = [alicloud_db_database.config_center.data_base_name]
  privilege    = "ReadWrite"
}

locals {
  rds_host = local.rds_public_connection_string
  rds_port = tonumber(local.rds_instance.port)

  rds_cluster_service_db                   = alicloud_db_database.cluster_service.data_base_name
  rds_cluster_service_username             = alicloud_rds_account.cluster_service.account_name
  rds_cluster_service_password_secret_name = alicloud_kms_secret.cluster_service.secret_name

  rds_config_center_db                   = alicloud_db_database.config_center.data_base_name
  rds_config_center_username             = alicloud_rds_account.config_center.account_name
  rds_config_center_password_secret_name = alicloud_kms_secret.config_center.secret_name
}
