locals {
  subnet_sets = merge(local.service_specific_private_subnets, { "default" = local.default_private_subnets })
  subnet_region_map = {
    for pair in flatten([
      for subnet_name, subnet_list in local.subnet_sets : [
        for region in var.resource_share_regions : {
          key         = region == "us-east-1" ? subnet_name : "${subnet_name}-${region}"
          subnet_name = subnet_name
          subnet_list = subnet_list
          region      = region
        }
      ]
    ]) : pair.key => pair
  }
}

resource "aws_ec2_managed_prefix_list" "service_specific_private_subnets" {
  for_each       = local.subnet_region_map
  region         = each.value.region
  address_family = "IPv4"
  max_entries    = length(each.value.subnet_list)
  name           = "${var.environment}-${var.account_group}-${each.value.subnet_name}-private-subnet-prefix-list"

  dynamic "entry" {
    for_each = each.value.subnet_list
    content {
      cidr        = entry.value["cidr_block"]
      description = "${var.environment} ${var.account_group} ${each.value.subnet_name} private subnet ${entry.value["cidr_block"]} in ${entry.value["availability_zone"]}"
    }
  }

  tags = merge(local.common_tags, {
    service_name = "managed-prefix-list"
    subnet_type  = "private"
    tier         = "private"
    vpc_id       = module.vpc.vpc_id
  })
}

resource "aws_ram_resource_share" "service_specific_private_subnets" {
  for_each = local.subnet_region_map
  region   = each.value.region

  name = "${var.environment}-${var.account_group}-${each.value.subnet_name}-private-subnet-managed-prefix-list-share${each.value.region == "us-east-1" ? "" : "-${each.value.region}"}"

  tags = merge(local.common_tags, {
    service_name = "managed-prefix-list"
  })
}

resource "aws_ram_resource_association" "private_subnet_association" {
  for_each = local.subnet_region_map
  region   = each.value.region

  resource_arn       = aws_ec2_managed_prefix_list.service_specific_private_subnets[each.key].arn
  resource_share_arn = aws_ram_resource_share.service_specific_private_subnets[each.key].arn
}

resource "aws_ram_principal_association" "private_subnet_principal_association" {
  for_each = {
    for combination in setproduct(keys(local.subnet_region_map), var.resource_share_principals) :
    "${combination[0]}.${combination[1]}" => {
      prefix_list = combination[0]
      principal   = combination[1]
      region      = local.subnet_region_map[combination[0]].region
    }
  }
  region             = each.value.region
  principal          = each.value.principal
  resource_share_arn = aws_ram_resource_share.service_specific_private_subnets[each.value.prefix_list].arn
}


# This shares the PL for the default private subnets (rather than ALL private subnets) with additional SME principals
resource "aws_ram_principal_association" "default_private_subnet_principal_association_with_additional_sme_principals" {
  for_each = {
    for combination in setproduct(
      [for prefix_list in keys(local.subnet_region_map) : prefix_list if startswith(prefix_list, "default")],
    var.sme_principals_for_default_private_subnet_share) :
    "${combination[0]}.${combination[1]}" => {
      prefix_list = combination[0]
      principal   = combination[1]
      region      = local.subnet_region_map[combination[0]].region
    }
  }
  region             = each.value.region
  principal          = each.value.principal
  resource_share_arn = aws_ram_resource_share.service_specific_private_subnets[each.value.prefix_list].arn
}

