# Security groups ============================================================

resource "aws_security_group" "this" {
  for_each = var.security_groups

  name        = local.sg_names[each.key]
  description = each.value.description
  vpc_id      = var.vpc_id

  # Managed rules are defined separately — remove default inline rules
  lifecycle {
    create_before_destroy = true
  }

  tags = merge(var.tags, local.module_tags, {
    Name          = local.sg_names[each.key]
    resource-type = "security-group"
  })
}

# Ingress rules --------------------------------------------------------------

resource "aws_vpc_security_group_ingress_rule" "this" {
  for_each = local.ingress_rule_map

  security_group_id = aws_security_group.this[each.value.sg_key].id

  description = each.value.rule.description
  ip_protocol = each.value.rule.protocol
  from_port   = each.value.rule.protocol == "-1" ? null : each.value.rule.from_port
  to_port     = each.value.rule.protocol == "-1" ? null : each.value.rule.to_port

  cidr_ipv4 = each.value.source_type == "cidr4" ? each.value.source_value : null
  cidr_ipv6 = each.value.source_type == "cidr6" ? each.value.source_value : null
  referenced_security_group_id = (
    each.value.source_type == "sg" ? (
      startswith(each.value.source_value, "key:")
      ? aws_security_group.this[trimprefix(each.value.source_value, "key:")].id
      : trimprefix(each.value.source_value, "id:")
    ) :
    each.value.source_type == "self" ? aws_security_group.this[each.value.sg_key].id :
    null
  )

  tags = merge(var.tags, local.module_tags, {
    Name = "${local.sg_names[each.value.sg_key]}-ingress-${
      each.value.source_type == "cidr4" ? "ipv4-cidr" :
      each.value.source_type == "cidr6" ? "ipv6-cidr" :
      each.value.source_type == "sg" ? "sg" :
      "self"
    }"
    resource-type = "security-group-rule"
  })
}

# Egress rules ---------------------------------------------------------------

resource "aws_vpc_security_group_egress_rule" "this" {
  for_each = local.egress_rule_map

  security_group_id = aws_security_group.this[each.value.sg_key].id

  description = each.value.rule.description
  ip_protocol = each.value.rule.protocol
  from_port   = each.value.rule.protocol == "-1" ? null : each.value.rule.from_port
  to_port     = each.value.rule.protocol == "-1" ? null : each.value.rule.to_port

  cidr_ipv4 = each.value.source_type == "cidr4" ? each.value.source_value : null
  cidr_ipv6 = each.value.source_type == "cidr6" ? each.value.source_value : null
  referenced_security_group_id = (
    each.value.source_type == "sg" ? (
      startswith(each.value.source_value, "key:")
      ? aws_security_group.this[trimprefix(each.value.source_value, "key:")].id
      : trimprefix(each.value.source_value, "id:")
    ) :
    each.value.source_type == "self" ? aws_security_group.this[each.value.sg_key].id :
    null
  )

  tags = merge(var.tags, local.module_tags, {
    Name = "${local.sg_names[each.value.sg_key]}-egress-${
      each.value.source_type == "cidr4" ? "ipv4-cidr" :
      each.value.source_type == "cidr6" ? "ipv6-cidr" :
      each.value.source_type == "sg" ? "sg" :
      "self"
    }"
    resource-type = "security-group-rule"
  })
}
