locals {
  jenkins_all_routetables = [
    module.jenkins_public_routing.route_table_id,
    module.jenkins_private_routing.route_table_id,
  ]
}

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

  name_prefix       = "${local.name_prefix}-jenkins"
  cidr_second_octet = var.jenkins_vpc["cidr_second_octet"]

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

  common_tags = {
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

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

  name_prefix        = "${local.name_prefix}-jenkins"
  subnets            = var.public_subnets
  vpc_id             = module.jenkins_vpc.vpc_id
  is_public          = true
  cidr_second_octet  = var.jenkins_vpc["cidr_second_octet"]
  availability_zones = local.availability_zones

  common_tags = {
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

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

  is_public   = true
  name_prefix = "${local.name_prefix}-jenkins"
  vpc_id      = module.jenkins_vpc.vpc_id
  vpc_cidr    = module.jenkins_vpc.vpc_cidr
  igw_id      = module.jenkins_vpc.vpc_igw
  subnets     = module.jenkins_public_subnets.subnet_ids

  common_tags = {
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

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

  name_prefix        = "${local.name_prefix}-jenkins"
  subnets            = var.private_subnets
  vpc_id             = module.jenkins_vpc.vpc_id
  is_public          = false
  cidr_second_octet  = var.jenkins_vpc["cidr_second_octet"]
  availability_zones = local.availability_zones

  common_tags = {
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

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

  name_prefix = "${local.name_prefix}-jenkins"
  # Not using NAT gateway redundancy in dev
  public_subnet_ids = [module.jenkins_public_subnets.subnet_ids[1]]

  common_tags = {
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

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

  is_public      = false
  name_prefix    = "${local.name_prefix}-jenkins"
  vpc_id         = module.jenkins_vpc.vpc_id
  vpc_cidr       = module.jenkins_vpc.vpc_cidr
  nat_gateway_id = module.jenkins_nat_gateways.nats[0].id
  subnets        = module.jenkins_private_subnets.subnet_ids

  common_tags = {
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

module "jenkins_sg_map" {
  source = "../../modules/sg_map_jenkins"

  name_prefix             = "${local.name_prefix}-jenkins"
  vpc_id                  = module.jenkins_vpc.vpc_id
  vpn_masq_cidrs          = ["10.50.12.148/32"]
  projectgroup_whitelist  = concat(var.projectgroup_whitelist, var.jenkins_whitelist)
  external_https_access   = concat(var.external_https_access, var.artistapp_team)
  external_access_mode    = "mixed"
  github_ip_addr          = var.github_ip_addr
  managed_prefix_list_ids = [data.aws_ec2_managed_prefix_list.vpn_ny_users.id]

  common_tags = {
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

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

  service      = "s3"
  vpc_id       = module.jenkins_vpc.vpc_id
  route_tables = local.jenkins_all_routetables

  common_tags = {
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

data "aws_vpc_endpoint_service" "secretsmanager" {
  service = "secretsmanager"
}

resource "aws_vpc_endpoint" "secretsmanager" {
  vpc_endpoint_type   = "Interface"
  vpc_id              = module.jenkins_vpc.vpc_id
  service_name        = data.aws_vpc_endpoint_service.secretsmanager.service_name
  private_dns_enabled = true
  subnet_ids          = module.jenkins_private_subnets.subnet_ids
  security_group_ids  = [module.jenkins_sg_map.endpoint_id]

  tags = {
    Name                     = "${local.name_prefix}-jenkins-secretsmanager-endpoint",
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

resource "aws_vpc_endpoint" "ecr-dkr-endpoint" {
  vpc_endpoint_type   = "Interface"
  vpc_id              = module.jenkins_vpc.vpc_id
  service_name        = "com.amazonaws.${var.aws_region_id}.ecr.dkr"
  private_dns_enabled = true
  subnet_ids          = module.jenkins_private_subnets.subnet_ids
  security_group_ids  = [module.jenkins_sg_map.endpoint_id]

  tags = {
    Name                     = "${local.name_prefix}-jenkins-ecr-dkr-endpoint",
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

resource "aws_vpc_endpoint" "ecr-api-endpoint" {
  service_name        = "com.amazonaws.${var.aws_region_id}.ecr.api"
  vpc_endpoint_type   = "Interface"
  vpc_id              = module.jenkins_vpc.vpc_id
  private_dns_enabled = true
  subnet_ids          = module.jenkins_private_subnets.subnet_ids
  security_group_ids  = [module.jenkins_sg_map.endpoint_id]

  tags = {
    Name                     = "${local.name_prefix}-jenkins-ecr-api-endpoint",
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}
resource "aws_vpc_endpoint" "ecs-agent" {
  service_name        = "com.amazonaws.${var.aws_region_id}.ecs-agent"
  vpc_endpoint_type   = "Interface"
  vpc_id              = module.jenkins_vpc.vpc_id
  private_dns_enabled = true
  subnet_ids          = module.jenkins_private_subnets.subnet_ids
  security_group_ids  = [module.jenkins_sg_map.endpoint_id]

  tags = {
    Name                     = "${local.name_prefix}-jenkins-ecs-agent-endpoint",
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}
resource "aws_vpc_endpoint" "ecs-telemetry" {
  service_name        = "com.amazonaws.${var.aws_region_id}.ecs-telemetry"
  vpc_endpoint_type   = "Interface"
  vpc_id              = module.jenkins_vpc.vpc_id
  private_dns_enabled = true
  subnet_ids          = module.jenkins_private_subnets.subnet_ids
  security_group_ids  = [module.jenkins_sg_map.endpoint_id]

  tags = {
    Name                     = "${local.name_prefix}-jenkins-ecs-telemetry-endpoint",
    service                  = "Networking",
    plat_env_project_service = "${local.aggregated_tag}_NTW"
  }
}

module "gsirt_regional_endpoints" {
  source = "../../../modules/gsirt_regional_endpoints"
}

module "jenkins_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.jenkins_private_subnets.subnet_ids
  vpc_id            = module.jenkins_vpc.vpc_id
  cidr_second_octet = var.jenkins_vpc["cidr_second_octet"]

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

module "jenkins_peering_delphi_dev" {
  source = "../../../modules/vpc/peering/one-to-one-external"

  vpc_requester_cidr  = "10.53.0.0/16"
  vpc_accepter_cidr   = "10.30.0.0/16"
  connection_name     = "INFRA_JENKINS_TO_DLP_DEV"
  accepter_account_id = module.aws_accounts_list.accounts["gdb-delphi-dev"]

  providers = {
    aws.requester = aws
    aws.accepter  = aws.gdb-delphi-dev
  }

  common_tags = {
    service                  = "VPN",
    plat_env_project_service = "${local.aggregated_tag}_VPN"
  }
}

module "jenkins_peering_delphi_qa" {
  source = "../../../modules/vpc/peering/one-to-one-external"

  vpc_requester_cidr  = "10.53.0.0/16"
  vpc_accepter_cidr   = "10.31.0.0/16"
  connection_name     = "INFRA_JENKINS_TO_DLP_QA"
  accepter_account_id = module.aws_accounts_list.accounts["gdb-delphi-dev"]

  providers = {
    aws.requester = aws
    aws.accepter  = aws.gdb-delphi-dev
  }

  common_tags = {
    service                  = "VPN",
    plat_env_project_service = "${local.aggregated_tag}_VPN"
  }
}

module "jenkins_peering_delphi_stage" {
  source = "../../../modules/vpc/peering/one-to-one-external"

  vpc_requester_cidr  = "10.53.0.0/16"
  vpc_accepter_cidr   = "10.32.0.0/16"
  connection_name     = "INFRA_JENKINS_TO_DLP_STAGE"
  accepter_account_id = module.aws_accounts_list.accounts["gdb-delphi-dev"]

  providers = {
    aws.requester = aws
    aws.accepter  = aws.gdb-delphi-dev
  }

  common_tags = {
    service                  = "VPN",
    plat_env_project_service = "${local.aggregated_tag}_VPN"
  }
}

module "jenkins_peering_infra" {
  source = "../../../modules/vpc/peering/one-to-one-internal"

  vpc_requester_cidr = "10.53.0.0/16"
  vpc_accepter_cidr  = "10.50.0.0/16"
  connection_name    = "JENKINS_TO_INFRA"

  common_tags = {
    service                  = "VPN",
    plat_env_project_service = "${local.aggregated_tag}_VPN"
  }
}

module "jenkins_peering_apollo_dev" {
  source = "../../../modules/vpc/peering/one-to-one-external"

  vpc_requester_cidr  = "10.53.0.0/16"
  vpc_accepter_cidr   = "10.10.0.0/16"
  connection_name     = "INFRA_JENKINS_TO_ALP_DEV"
  accepter_account_id = module.aws_accounts_list.accounts["gdb-delphi-dev"]

  providers = {
    aws.requester = aws
    aws.accepter  = aws.gdb-delphi-dev
  }

  common_tags = {
    service                  = "VPN",
    plat_env_project_service = "${local.aggregated_tag}_VPN"
  }
}

data "aws_ec2_transit_gateway" "transit_gateway" {
  filter {
    name   = "options.amazon-side-asn"
    values = ["64513"]
  }
}

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

data "aws_ec2_managed_prefix_list" "vpn_sme" {
  filter {
    name   = "prefix-list-name"
    values = ["vpn-sme-internal-primary"]
  }
}

resource "aws_ec2_transit_gateway_vpc_attachment" "transit_gateway_attachment" {
  vpc_id             = module.jenkins_vpc.vpc_id
  transit_gateway_id = data.aws_ec2_transit_gateway.transit_gateway.id
  subnet_ids = concat(
    module.jenkins_private_subnets.subnet_ids,
  )
}

resource "aws_route" "ny" {
  for_each = toset([module.jenkins_private_routing.route_table_id, module.jenkins_public_routing.route_table_id])

  route_table_id             = each.value
  destination_prefix_list_id = data.aws_ec2_managed_prefix_list.vpn_ny_users.id
  transit_gateway_id         = data.aws_ec2_transit_gateway.transit_gateway.id
}

resource "aws_route" "sme" {
  for_each = toset([
    module.jenkins_private_routing.route_table_id,
    module.jenkins_public_routing.route_table_id,
  ])

  route_table_id             = each.value
  destination_prefix_list_id = data.aws_ec2_managed_prefix_list.vpn_sme.id
  transit_gateway_id         = data.aws_ec2_transit_gateway.transit_gateway.id
}
