module "main_vpc" {
  source = "../../../modules/vpc/vpc_v2"

  name_prefix       = local.name_prefix
  cidr_second_octet = var.vpc["cidr_second_octet"]

  flow_logs = {
    gsirt = {
      log_destination      = "${data.aws_s3_bucket.logs.arn}/vpcflow/"
      log_destination_type = "s3"
      traffic_type         = "REJECT"
    }
  }

  common_tags = merge(
    local.common_tags,
    {
      project                  = "Infrastructure",
      service                  = "Networking",
      plat_env_project_service = "${local.aggregated_tag}_INFRA_NTW"
    }
  )
}

module "main_public_subnets" {
  source = "../../../modules/vpc/subnet"

  name_prefix        = local.name_prefix
  subnets            = var.public_subnets
  vpc_id             = module.main_vpc.vpc_id
  is_public          = true
  cidr_second_octet  = var.vpc["cidr_second_octet"]
  availability_zones = local.availability_zones

  common_tags = merge(
    local.common_tags,
    {
      project                  = "Infrastructure",
      service                  = "Networking",
      plat_env_project_service = "${local.aggregated_tag}_INFRA_NTW"
    }
  )
}

module "main_public_routing" {
  source = "../../../modules/vpc/routes"

  is_public   = true
  name_prefix = local.name_prefix
  vpc_id      = module.main_vpc.vpc_id
  vpc_cidr    = module.main_vpc.vpc_cidr
  igw_id      = module.main_vpc.vpc_igw
  subnets     = module.main_public_subnets.subnet_ids

  common_tags = merge(
    local.common_tags,
    {
      project                  = "Infrastructure",
      service                  = "Networking",
      plat_env_project_service = "${local.aggregated_tag}_INFRA_NTW"
    }
  )
}

module "main_private_subnets" {
  source = "../../../modules/vpc/subnet"

  name_prefix        = local.name_prefix
  subnets            = var.private_subnets
  vpc_id             = module.main_vpc.vpc_id
  is_public          = false
  cidr_second_octet  = var.vpc["cidr_second_octet"]
  availability_zones = local.availability_zones

  common_tags = merge(
    local.common_tags,
    {
      project                  = "Infrastructure",
      service                  = "Networking",
      plat_env_project_service = "${local.aggregated_tag}_INFRA_NTW"
    }
  )
}


module "main_nat_gateways" {
  source = "../../../modules/vpc/nat"

  name_prefix = local.name_prefix
  # Not using NAT gateway redundancy in dev
  public_subnet_ids = [module.main_public_subnets.subnet_ids[1]]

  common_tags = merge(
    local.common_tags,
    {
      project                  = "Infrastructure",
      service                  = "Networking",
      plat_env_project_service = "${local.aggregated_tag}_INFRA_NTW"
    }
  )
}

# In some environments it's better to create multiple nat gateways, one per availability zone.
module "main_private_routing" {
  source = "../../../modules/vpc/routes"

  is_public      = false
  name_prefix    = local.name_prefix
  vpc_id         = module.main_vpc.vpc_id
  vpc_cidr       = module.main_vpc.vpc_cidr
  nat_gateway_id = module.main_nat_gateways.nats[0].id
  subnets        = module.main_private_subnets.subnet_ids

  common_tags = merge(
    local.common_tags,
    {
      project                  = "Infrastructure",
      service                  = "Networking",
      plat_env_project_service = "${local.aggregated_tag}_INFRA_NTW"
    }
  )
}

/* Disabling since we need cross-region bucket access
module s3_endpoint {
  source        = "../../../modules/vpc/endpoint_gateway"
  service       = "s3"
  vpc_id        = module.main_vpc.vpc_id
  route_tables  = local.all_routetables
  common_tags = merge(
    local.common_tags,
    {
      project                  = "Infrastructure",
      service                  = "Networking",
      plat_env_project_service = "${local.aggregated_tag}_INFRA_NTW"
    }
  )
}*/

module "dynamodb_endpoint" {
  source = "../../../modules/vpc/endpoint_gateway"

  service      = "dynamodb"
  vpc_id       = module.main_vpc.vpc_id
  route_tables = local.all_routetables

  common_tags = merge(
    local.common_tags,
    {
      project                  = "Infrastructure",
      service                  = "Networking",
      plat_env_project_service = "${local.aggregated_tag}_INFRA_NTW"
    }
  )
}

module "gsirt_endpoint" {
  source = "../../../modules/vpc/endpoint_gateway"

  service           = module.gsirt_regional_endpoints.regional_endpoints_service_name[var.aws_region_id]
  vpc_endpoint_type = "Interface"
  subnet_ids        = module.main_private_subnets.subnet_ids
  vpc_id            = module.main_vpc.vpc_id
  cidr_second_octet = var.vpc["cidr_second_octet"]

  common_tags = merge(
    local.common_tags,
    {
      Name                     = format("%v-gsirt-endpoint", local.name_prefix)
      project                  = "Infrastructure",
      service                  = "Networking",
      plat_env_project_service = "${local.aggregated_tag}_INFRA_NTW"
    }
  )
}

resource "aws_security_group_rule" "apollo_new_mysql" {
  for_each = toset([
    "725764004555/sg-088b7987c701f3c13", // dev ecs
    "725764004555/sg-066fb93f0320f4469", // qa ecs
    "725764004555/sg-04579b0d29529247b", // stage ecs
    "725764004555/sg-0dbd02b4a16d6a211", // dev lambda
    "725764004555/sg-0b6bf6dd208c15b12", // qa lambda
    "725764004555/sg-0df6007d8313d2234", // stage lambda
    "725764004555/sg-04b599cbe77e480b0", // new .net
    "725764004555/sg-0e90af6f312ade8ea", // new .net etl
  ])
  from_port                = 3306
  to_port                  = 3306
  type                     = "ingress"
  security_group_id        = module.main_sg_map.aurora_id
  protocol                 = "tcp"
  source_security_group_id = each.key
  description              = "Access from new Apollo dev"
}

resource "aws_security_group_rule" "apollo_new_docdb" {
  for_each = toset([
    "725764004555/sg-088b7987c701f3c13", // dev ecs
    "725764004555/sg-066fb93f0320f4469", // qa ecs
    "725764004555/sg-04579b0d29529247b", // stage ecs
    "725764004555/sg-0dbd02b4a16d6a211", // dev lambda
    "725764004555/sg-0b6bf6dd208c15b12", // qa lambda
    "725764004555/sg-0df6007d8313d2234", // stage lambda
  ])
  from_port                = 27017
  to_port                  = 27019
  type                     = "ingress"
  security_group_id        = module.main_sg_map.docdb_id
  protocol                 = "tcp"
  source_security_group_id = each.key
  description              = "Access from new Apollo dev"
}

# Add nat IP to ALB security group
resource "aws_security_group_rule" "alb_nat" {
  type              = "ingress"
  description       = "From nat to alb"
  protocol          = "tcp"
  security_group_id = module.main_sg_map.alb_id
  cidr_blocks       = formatlist("%v/32", module.main_nat_gateways.cidrs)
  from_port         = 443
  to_port           = 443
}

# Databricks dev rule
resource "aws_security_group_rule" "databricks_mysql" {
  from_port         = 3306
  to_port           = 3306
  type              = "ingress"
  security_group_id = module.main_sg_map.aurora_id
  protocol          = "tcp"
  cidr_blocks       = ["10.163.0.0/16"]
  description       = "Access from databricks"
}

resource "aws_security_group_rule" "databricks_mysql_v2" {
  from_port         = 3306
  to_port           = 3306
  type              = "ingress"
  security_group_id = module.main_sg_map.aurora_id
  protocol          = "tcp"
  description       = "Access from databricks"

  source_security_group_id = "745243859288/sg-00ee3b0379bd27140"
}

resource "aws_security_group_rule" "delphi_mysql" {
  from_port         = 3306
  to_port           = 3306
  type              = "ingress"
  security_group_id = module.main_sg_map.aurora_id
  protocol          = "tcp"
  description       = "Access from delphi peering connections"
  cidr_blocks = [
    "10.30.13.0/24", "10.30.14.0/24", "10.30.15.0/24",
    "10.31.13.0/24", "10.31.14.0/24", "10.31.15.0/24",
    "10.32.13.0/24", "10.32.14.0/24", "10.32.15.0/24",
  ]
}

resource "aws_security_group_rule" "apollo_new_redis" {
  for_each = toset([
    "725764004555/sg-088b7987c701f3c13",
    "725764004555/sg-04b599cbe77e480b0",
    "725764004555/sg-0e90af6f312ade8ea", // new .net etl
  ])
  from_port                = 6379
  protocol                 = "tcp"
  security_group_id        = module.main_sg_map.redis_id
  to_port                  = 6379
  type                     = "ingress"
  source_security_group_id = each.key
}

resource "aws_security_group_rule" "jenkins_agent_mysql" {
  from_port                = 3306
  to_port                  = 3306
  type                     = "ingress"
  security_group_id        = module.main_sg_map.aurora_id
  protocol                 = "tcp"
  description              = "Access from Jenkins VPC"
  source_security_group_id = "483193324480/sg-09671f86e35ddf847"
}

data "aws_ec2_managed_prefix_list" "vpn_ny_users" {
  filter {
    name   = "prefix-list-name"
    values = ["vpn-ny-users"]
  }
}
