locals {
  ingress-alb = [
    { from_port = 80, to_port = 80, source_sg_id = module.sg-alb.sg_id, description = "Allow inbound http from ALBs" },
    { from_port = 80, to_port = 80, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound http from ECS containers" },
    { from_port = 443, to_port = 443, source_sg_id = module.sg-alb.sg_id, description = "Allow inbound https from ALBs" },
    { from_port = 443, to_port = 443, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound https from ECS containers" },
  ]
  ingress-ecs = [
    { from_port = 8080, to_port = 8080, source_sg_id = module.sg-alb.sg_id, description = "Allow inbound connections from ALBs" },
    { from_port = 8080, to_port = 8080, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound connections from ECS" },
  ]
  ingress-rds = [
    // { from_port = 3306, to_port = 3306, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound connections from ECS" },
    // { from_port = 5432, to_port = 5432, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound connections from ECS" },
  ]

  ingress-efs = [
    { from_port = 2049, to_port = 2049, source_sg_id = module.sg-ecs.sg_id, description = "Allow inbound nfs from ECS" },
    { from_port = 2049, to_port = 2049, source_sg_id = module.sg-efs.sg_id, description = "Allow inbound nfs from EFS" },
  ]
  whitelisted_cidrs = concat(module.ip_whitelist.whitelist_for_sg, var.projectgroup_whitelist)
  # If vpn_enabled, management and debug SG will give access to vpn cidrs instead of office IP whitelist
  vpn_cidrs = [for cidr in var.vpn_masq_cidrs : { cidr = cidr, description = "Access for VPN users" }]
  env_access_list = var.external_access_mode == "whitelist" ? local.whitelisted_cidrs : (
    var.external_access_mode == "vpn" ? local.vpn_cidrs : concat(local.vpn_cidrs, local.whitelisted_cidrs)
  )
  whitelisted_ip_sets = [for item in concat(local.env_access_list, var.external_https_access) : {
    type  = "IPV4"
    value = item["cidr"]
  }]
}

module "ip_whitelist" {
  source = "../../modules/ip_whitelist_v2"
}

# Create security group for load balancers
module "sg-alb" {
  source = "../../modules/vpc/sg"

  name             = "${var.name_prefix}-sg-alb"
  sg_description   = "Allows HTTP connections to ALB"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-alb

  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-alb", var.name_prefix)
    },
  )
}

# Create security group for containers in ECS
module "sg-ecs" {
  source = "../../modules/vpc/sg"

  name             = "${var.name_prefix}-sg-ecs"
  sg_description   = "Allows HTTP connections to ECS"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-ecs

  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-ecs", var.name_prefix)
    },
  )
}

# Create security group for EFS
module "sg-efs" {
  source = "../../modules/vpc/sg"

  name             = "${var.name_prefix}-sg-efs"
  sg_description   = "Allows NFS connections to EFS"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-efs

  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-efs", var.name_prefix)
    },
  )
}

# Create security group for RDS
module "sg-rds" {
  source = "../../modules/vpc/sg"

  name             = "${var.name_prefix}-sg-rds"
  sg_description   = "Allows access to RDS"
  vpc_id           = var.vpc_id
  protocol         = "tcp"
  ingress_template = local.ingress-rds

  tags = merge(
    var.common_tags,
    {
      "Name" = format("%v-sg-rds", var.name_prefix)
    },
  )
}

resource "aws_security_group" "remote_management_access" {
  name        = "${var.name_prefix}-sg-remote-access"
  description = "Allow connections via SSH from specified addresses"
  vpc_id      = var.vpc_id

  # SSH
  dynamic "ingress" {
    for_each = local.env_access_list

    content {
      description = ingress.value["description"]
      from_port   = 22
      to_port     = 22
      protocol    = "tcp"
      cidr_blocks = [ingress.value["cidr"]]
    }
  }

  egress {
    description = "Allow all outbound traffic."
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = merge(
    var.common_tags,
    {
      "Name"           = format("%v-sg-remote-access", var.name_prefix),
      "eiso-exception" = "aws.08.30",
    },
  )

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_security_group" "web_http_debug_access" {
  name        = "${var.name_prefix}-sg-http-debug"
  description = "Allow HTTP connections from specified addresses"
  vpc_id      = var.vpc_id

  dynamic "ingress" {
    for_each = local.env_access_list

    content {
      description = ingress.value["description"]
      from_port   = 80
      to_port     = 80
      protocol    = "tcp"
      cidr_blocks = [ingress.value["cidr"]]
    }
  }

  egress {
    description = "Allow all outbound traffic."
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = merge(
    var.common_tags,
    {
      "Name"           = format("%v-sg-http-debug", var.name_prefix),
      "eiso-exception" = "aws.08.30",
    },
  )
}

resource "aws_security_group" "web_https_debug_access" {
  name        = "${var.name_prefix}-sg-https-debug"
  description = "Allow HTTPS connections from specified addresses"
  vpc_id      = var.vpc_id

  dynamic "ingress" {
    for_each = local.env_access_list

    content {
      description = ingress.value["description"]
      from_port   = 443
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = [ingress.value["cidr"]]
    }
  }

  egress {
    description = "Allow all outbound traffic."
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = merge(
    var.common_tags,
    {
      "Name"           = format("%v-sg-https-debug", var.name_prefix),
      "eiso-exception" = "aws.08.30",
    },
  )
}

resource "aws_security_group" "db_debug_access" {
  name        = "${var.name_prefix}-sg-db-debug"
  description = "Allow connections db ports from specified addresses"
  vpc_id      = var.vpc_id

  #  dynamic "ingress" {
  #    for_each = local.env_access_list
  #
  #    content {
  #      description = ingress.value["description"]
  #      from_port   = 3306
  #      to_port     = 3306
  #      protocol    = "tcp"
  #      cidr_blocks = [ingress.value["cidr"]]
  #    }
  #
  #    content {
  #      description = ingress.value["description"]
  #      from_port   = 5432
  #      to_port     = 5432
  #      protocol    = "tcp"
  #      cidr_blocks = [ingress.value["cidr"]]
  #    }
  #  }

  egress {
    description = "Allow all outbound traffic."
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = merge(
    var.common_tags,
    {
      "Name"           = format("%v-sg-db-debug", var.name_prefix),
      "eiso-exception" = "aws.08.30",
    },
  )
}

resource "aws_security_group" "ext_web_sg" {
  name        = "${var.name_prefix}-sg-external-https"
  description = "HTTPS access for list of external ip addresses"
  vpc_id      = var.vpc_id

  dynamic "ingress" {
    # In case VPN is enabled, add whitelisted IP addresses to the SG
    for_each = var.external_access_mode == "vpn" ? concat(var.external_https_access, local.whitelisted_cidrs) : var.external_https_access
    content {
      description = ingress.value["description"]
      from_port   = 443
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = [ingress.value["cidr"]]
    }
  }

  tags = merge(
    var.common_tags,
    {
      Name = "${var.name_prefix}-sg-external-https"
    },
  )
}

resource "aws_security_group" "public_access_sg" {
  name        = "${var.name_prefix}-sg-public-access"
  description = "HTTP(s) public access"
  vpc_id      = var.vpc_id

  ingress {
    description = "Allow port 80 inbound traffic."
    from_port   = 80
    protocol    = "tcp"
    to_port     = 80
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "Allow port 443 inbound traffic."
    from_port   = 443
    protocol    = "tcp"
    to_port     = 443
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    description = "Allow all outbound traffic."
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = merge(
    var.common_tags,
    {
      Name             = "${var.name_prefix}-sg-public-access",
      "eiso-exception" = "aws.08.30",
    },
  )
}
