resource "random_integer" "port_base" {
  min = 20000
  max = 60000
}

resource "random_password" "mysql_root" {
  length  = 32
  special = false
}

resource "random_password" "mysql" {
  length  = 32
  special = false
}

resource "random_string" "kafka_username" {
  length  = 8
  upper   = false
  special = false
}

resource "random_password" "kafka" {
  length  = 32
  special = false
}

resource "random_string" "schema_registry_username" {
  length  = 8
  upper   = false
  special = false
}

resource "random_password" "schema_registry" {
  length  = 32
  special = false
}

resource "random_id" "pulsar_secret" {
  byte_length = 32
}

resource "random_id" "kafka_cluster_id" {
  byte_length = 16
}

resource "random_id" "deployment" {
  byte_length = 6
}

locals {
  deployment_name = "${var.name_prefix}-${random_id.deployment.hex}"
  base_tags = {
    Environment        = "test"
    ManagedBy          = "terraform"
    Owner              = "date-integration"
    Project            = var.name_prefix
    DataClassification = "test"
  }
  deployment_tags = {
    usedby = local.deployment_name
  }
  common_tags = merge(local.base_tags, local.deployment_tags)

  s3_bucket_name        = coalesce(var.s3_bucket_name, "${local.deployment_name}-${var.target_account_id}-${var.aws_region}")
  s3_cdc_uri            = "s3://${local.s3_bucket_name}/cdc/"
  s3_backup_export_uri  = "s3://${local.s3_bucket_name}/backup-export/"
  s3_cluster_export_uri = "s3://${local.s3_bucket_name}/cluster-export/"
  s3_import_uri         = "s3://${local.s3_bucket_name}/import/"
  s3_assume_role_external_ids_by_account = {
    for account_id in toset([for grant in values(var.s3_assume_role_grants) : grant.account_id]) : account_id => sort([
      for grant in values(var.s3_assume_role_grants) : grant.external_id
      if grant.account_id == account_id
    ])
  }
  s3_role_trusted_principal_arns = coalesce(
    var.s3_role_trusted_principal_arns,
    toset(["arn:aws:iam::${var.target_account_id}:root"]),
  )
  e2e_s3_dependencies = [{
    bucketURI = local.s3_cdc_uri
    region    = var.aws_region
    roleARN   = aws_iam_role.s3_access.arn
  }]

  availability_zones    = data.aws_availability_zones.available.names
  availability_zone_ids = data.aws_availability_zones.available.zone_ids
  subnets = {
    for index, az in local.availability_zones : tostring(index) => {
      availability_zone    = az
      availability_zone_id = local.availability_zone_ids[index]
      cidr                 = cidrsubnet(var.vpc_cidr, 4, index)
    }
  }

  primary_az    = local.availability_zones[0]
  primary_az_id = local.availability_zone_ids[0]
  ami_id        = coalesce(var.ami_id, data.aws_ami.al2023.id)

  port_base = coalesce(var.port_base, random_integer.port_base.result)
  ports = {
    mysql             = local.port_base
    kafka_public      = local.port_base + 17
    kafka_sasl        = local.port_base + 41
    kafka_pl_public   = local.port_base + 73
    kafka_pl_sasl     = local.port_base + 109
    pulsar_binary     = local.port_base + 151
    pulsar_admin_http = local.port_base + 197
    schema_registry   = local.port_base + 239
  }

  public_ports = merge({
    mysql        = local.ports.mysql
    kafka_public = local.ports.kafka_public
    kafka_sasl   = local.ports.kafka_sasl
    }, var.enable_pulsar ? {
    pulsar_binary = local.ports.pulsar_binary
    pulsar_admin  = local.ports.pulsar_admin_http
    } : {}, var.enable_schema_registry ? {
    schema_registry = local.ports.schema_registry
  } : {})

  mysql_root_password      = coalesce(var.mysql_root_password, random_password.mysql_root.result)
  mysql_password           = coalesce(var.mysql_password, random_password.mysql.result)
  kafka_sasl_username      = coalesce(var.kafka_sasl_username, "e2e_${random_string.kafka_username.result}")
  kafka_sasl_password      = coalesce(var.kafka_sasl_password, random_password.kafka.result)
  schema_registry_username = coalesce(var.schema_registry_username, "e2e_${random_string.schema_registry_username.result}")
  schema_registry_password = coalesce(var.schema_registry_password, random_password.schema_registry.result)
  pulsar_token_secret      = coalesce(var.pulsar_token_secret, random_id.pulsar_secret.b64_std)
  kafka_cluster_id         = random_id.kafka_cluster_id.b64_url
  allowed_principal_arns = coalesce(
    var.allowed_principal_arns,
    toset([
      "arn:aws:iam::024848481520:root", # auto-deployment-test
      "arn:aws:iam::118688039167:root", # Date Integration producer account
      "arn:aws:iam::131464424160:root", # qa-dbaas-prod
      "arn:aws:iam::143458967504:root", # dbaas-prod-dataplane-000
      "arn:aws:iam::200683210682:root", # dbaas-infra-dev
      "arn:aws:iam::380838443567:root", # pingcap-dbaas
      "arn:aws:iam::385595570414:root", # PingCAP
      "arn:aws:iam::676546228356:root", # qa-dbaas-dev
      "arn:aws:iam::730335266318:root", # dbaas-prod-dataplane-001
    ]),
  )

  kafka_privatelink_zone_record = "${local.primary_az_id}.${var.kafka_privatelink_root_domain_name}"
  kafka_privatelink_advertised_host = coalesce(
    var.kafka_privatelink_advertised_host,
    "b1.${local.kafka_privatelink_zone_record}",
  )

  privatelink_enabled = var.desired_state == "running" || !var.remove_privatelink_when_stopped

  images = {
    mysql           = "mysql:8.4.11@sha256:b3b90af2a6552ae30c266fdb7d5dd55f3afb72404bb78d37fe8a23eb857fd3fb"
    kafka           = "apache/kafka:3.9.2@sha256:05b4616e0702ef2729327705d54ad6b50ea70b271c4b730fabd2320789fb7b02"
    pulsar          = "apachepulsar/pulsar:3.3.9@sha256:edb08c608371bc69a92a0edda255e869cef404577b9ca995cbe98e0c0de10e0e"
    kafka_proxy     = "grepplabs/kafka-proxy:0.4.3-all@sha256:95c1b7a1136613f630902aeec25909c35e1002d202dd3a3eb5d6188543775787"
    schema_registry = "confluentinc/cp-schema-registry:7.8.0@sha256:ae0695b092314be82fe32058c276d99224855090a77ec169423cf82e02d5e3ac"
  }
}

data "external" "pulsar_proxy_token" {
  program = ["python3", "${path.module}/../../scripts/create_pulsar_token.py"]
  query = {
    secret  = local.pulsar_token_secret
    subject = "proxy"
  }
}

data "external" "pulsar_admin_token" {
  program = ["python3", "${path.module}/../../scripts/create_pulsar_token.py"]
  query = {
    secret  = local.pulsar_token_secret
    subject = "admin"
  }
}

data "external" "pulsar_client_token" {
  program = ["python3", "${path.module}/../../scripts/create_pulsar_token.py"]
  query = {
    secret  = local.pulsar_token_secret
    subject = "e2e-client"
  }
}
