locals {
  states = {
    "base" : "aws/base/${var.env}.json",
    "seed" : "aws/account/seed/${var.env}.json",
    "clinic" : var.env == "dev" ? "aws/clinic/staging.json" : "aws/clinic/${var.env}.json",
    # we always use prod o11y global regardless of current deployment env
    "o11y" : "aws/o11y-global/prod.json",
  }
}

data "aws_s3_object" "states" {
  for_each = local.states
  bucket   = "autonomous-deployment-terraform-state"
  key      = each.value

  provider = aws.tf_state
}

locals {
  base_outputs                 = jsondecode(data.aws_s3_object.states["base"].body).outputs
  seed_outputs                 = jsondecode(data.aws_s3_object.states["seed"].body).outputs
  clinic_outputs               = jsondecode(data.aws_s3_object.states["clinic"].body).outputs
  o11y_outputs                 = jsondecode(data.aws_s3_object.states["o11y"].body).outputs
  base_account                 = local.seed_outputs.base_account.value
  seed_account                 = local.seed_outputs.seed_account.value
  seed_hosted_zone_name        = local.seed_outputs.hosted_zone_name.value
  seed_hosted_zone_id          = local.seed_outputs.hosted_zone_id.value
  clinic_endpoint_service_name = local.clinic_outputs.endpoint_service_name.value
}


# Fallback: read hosted zone IDs and PCA ARN from CloudFormation stacks when the
# corresponding vars are not set explicitly. These stacks are created by the
# tidbcloud/byoc-account-setup scripts that the customer is expected to run before
# provisioning. If a customer initialised their account via custom scripts (not
# CloudFormation), these data sources will fail — pass the three vars explicitly
# to skip these lookups.
data "aws_cloudformation_stack" "tidbcloud-byoc-setup-dataplane" {
  count = (var.tidb_hosted_zone_id == null || var.pca_arn == null) ? 1 : 0
  name  = "tidbcloud-byoc-setup-dataplane"

  provider = aws.cloudformation
}

data "aws_cloudformation_stack" "tidbcloud-byoc-setup-o11y" {
  count = var.o11y_hosted_zone_id == null ? 1 : 0
  name  = "tidbcloud-byoc-setup-o11y"

  provider = aws.cloudformation
}

locals {
  tidb_hosted_zone_id = var.tidb_hosted_zone_id != null ? var.tidb_hosted_zone_id : data.aws_cloudformation_stack.tidbcloud-byoc-setup-dataplane[0].parameters.HostedZoneId
  o11y_hosted_zone_id = var.o11y_hosted_zone_id != null ? var.o11y_hosted_zone_id : data.aws_cloudformation_stack.tidbcloud-byoc-setup-o11y[0].parameters.O11yHostedZoneId
  pca_arn             = var.pca_arn != null ? var.pca_arn : data.aws_cloudformation_stack.tidbcloud-byoc-setup-dataplane[0].parameters.PCAArn
}

data "aws_route53_zone" "shoot_hosted_zone" {
  zone_id = local.tidb_hosted_zone_id

  provider = aws.cloudformation
}

data "aws_route53_zone" "o11y_hosted_zone" {
  zone_id = local.o11y_hosted_zone_id

  provider = aws.cloudformation
}

module "seed" {
  source                 = "./seed"
  env                    = var.env
  aws_region             = var.aws_region
  logical_region_name    = var.logical_region_name
  enable_falco           = var.enable_falco
  availability_zones     = var.availability_zones
  dataplane_zone_names   = module.shoot.availability_zone_names
  dataplane_node_zones   = [module.shoot.node_group_availability_zone_name]
  dataplane_account      = var.dataplane_account
  o11y_account_id        = local.o11y_outputs.account.value
  o11y_write_nlb         = module.shoot.lb_nginx_w
  hosted_zone_name       = local.seed_hosted_zone_name
  hosted_zone_id         = local.seed_hosted_zone_id
  shoot_hosted_zone_id   = data.aws_route53_zone.shoot_hosted_zone.zone_id
  shoot_hosted_zone_name = data.aws_route53_zone.shoot_hosted_zone.name
  o11y_vpc_id            = module.shoot.vpc_id
  o11y_vpc_cidr          = module.shoot.vpc_cidr
  pca_arn                = local.pca_arn
  byoc_ecr               = var.byoc_ecr
  tenant_ids             = [var.byoc_tenant_id]
  eks                    = var.seed_eks
  vpc                    = var.seed_vpc
  enable_ecr_privatelink = try(var.shoot_vpc.enable_ecr_privatelink, true)

  providers = {
    aws.tf_state = aws.tf_state
  }
}

module "shoot" {
  source                       = "./shoot"
  env                          = var.env
  tags                         = var.shoot_tags
  aws_region                   = var.aws_region
  logical_region_name          = var.logical_region_name
  availability_zones           = var.availability_zones
  clinic_endpoint_service_name = local.clinic_endpoint_service_name
  sns_topic_arn                = local.o11y_outputs.sns_topic_arn.value
  o11y_account_id              = local.o11y_outputs.account.value
  byoc_tenant_id               = var.byoc_tenant_id
  byoc_ecr                     = var.byoc_ecr
  seed_account                 = local.seed_account
  o11y_hosted_zone_id          = data.aws_route53_zone.o11y_hosted_zone.zone_id
  o11y_hosted_zone_name        = data.aws_route53_zone.o11y_hosted_zone.name
  eks                          = var.shoot_eks
  vpc                          = var.shoot_vpc
  destroy_mode                 = var.destroy_mode

  providers = {
    aws          = aws.shoot
    aws.tf_state = aws.tf_state
    aws.seed     = aws
  }
}

output "seed_vpc_id" {
  value = module.seed.vpc_id
}

output "seed_vpc_route_table_ids" {
  value = module.seed.vpc_route_table_ids
}

output "shoot_vpc_id" {
  value = module.shoot.vpc_id
}

output "shoot_vpc_route_table_ids" {
  value = module.shoot.vpc_route_table_ids
}

output "seed_private_subnet_az_map" {
  value = module.seed.private_subnet_az_map
}

output "seed_public_subnet_az_map" {
  value = module.seed.public_subnet_az_map
}

output "shoot_private_subnet_az_map" {
  value = module.shoot.private_subnet_az_map
}

output "shoot_public_subnet_az_map" {
  value = module.shoot.public_subnet_az_map
}
