module "default_tags" {
  source             = "git@github.com:theorchard/terraform-default-tags.git//?ref=1.0.0"
  environment        = var.environment
  application_family = var.application_family
  service_name       = var.service_name
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = module.default_tags.tags
  }
}

terraform {
  backend "s3" {
    bucket  = "orcd-terraform-state"
    key     = "prod/vpc/us-east-1/switchboard/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

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

data "aws_s3_bucket" "flow_logs_bucket" {
  bucket = "prod-${var.account_group}-vpc-logs"
}

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

data "aws_ec2_managed_prefix_lists" "prefix_list_routes" {
  filter {
    name   = "prefix-list-name"
    values = var.vpc_routing_prefix_list_names
  }
}

data "aws_route53_resolver_firewall_rule_group" "dns_firewall_rule_group" {
  firewall_rule_group_id = "rslvr-frg-1764658298884585" # sony_ioc_rule_group
}

module "vpc" {
  source = "git@github.com:theorchard/terraform-vpc.git//modules/vpc?ref=4.1.1"

  account_group                          = var.account_group
  env                                    = var.environment
  vpc_cidr                               = "10.110.0.0/16"
  custom_vpc_name                        = "${var.environment}-graphql-switchboard-vpc"
  custom_elasticache_subnet_group_name   = "${var.environment}-${var.service_name}-elasticache-subnet-group"
  custom_private_subnet_prefix_list_name = "${var.environment}-${var.service_name}-private-subnet-prefix-list"
  custom_public_subnet_prefix_list_name  = "${var.environment}-${var.service_name}-public-subnet-prefix-list"
  dns_firewall_rule_group_id             = data.aws_route53_resolver_firewall_rule_group.dns_firewall_rule_group.id

  vpc_public_subnets = [
    { availability_zone = "us-east-1a", cidr_block = "10.110.10.0/24", name = "${var.environment}-graphql-switchboard-public-subnet-0" },
    { availability_zone = "us-east-1b", cidr_block = "10.110.11.0/24", name = "${var.environment}-graphql-switchboard-public-subnet-1" },
  ]

  vpc_private_subnets = [
    { availability_zone = "us-east-1a", cidr_block = "10.110.0.0/24", name = "${var.environment}-graphql-switchboard-private-subnet-0" },
    { availability_zone = "us-east-1b", cidr_block = "10.110.1.0/24", name = "${var.environment}-graphql-switchboard-private-subnet-1" },
  ]

  vpc_flow_logs = {
    gsirt = {
      log_destination      = data.aws_s3_bucket.flow_logs_bucket.arn
      log_destination_type = "s3"
      traffic_type         = "REJECT"
    }
  }
}

resource "aws_ec2_transit_gateway_vpc_attachment" "transit_gateway_attachment" {
  vpc_id             = module.vpc.vpc_id
  subnet_ids         = module.vpc.private_subnet_ids
  transit_gateway_id = data.aws_ec2_transit_gateway.transit_gateway.id
}

resource "aws_route" "public_transit_gateway_prefix_list_routes" {
  for_each = toset(data.aws_ec2_managed_prefix_lists.prefix_list_routes.ids)

  destination_prefix_list_id = each.value
  route_table_id             = module.vpc.public_route_table_id
  transit_gateway_id         = data.aws_ec2_transit_gateway.transit_gateway.id
}

resource "aws_route" "private_transit_gateway_routes" {
  for_each = {
    for pair in setproduct(
      var.vpc_private_subnet_transit_gateway_routes,
      module.vpc.private_route_table_ids
    ) :
    "${pair[0]}_${pair[1]}" => {
      prefix_list_id = pair[0]
      route_table_id = pair[1]
    }
  }
  destination_cidr_block = each.value.prefix_list_id
  route_table_id         = each.value.route_table_id
  transit_gateway_id     = data.aws_ec2_transit_gateway.transit_gateway.id
}

resource "aws_route" "private_transit_gateway_prefix_list_routes" {
  for_each = {
    for pair in setproduct(
      data.aws_ec2_managed_prefix_lists.prefix_list_routes.ids,
      module.vpc.private_route_table_ids
    ) :
    "${pair[0]}_${pair[1]}" => {
      prefix_list_id = pair[0]
      route_table_id = pair[1]
    }
  }
  destination_prefix_list_id = each.value.prefix_list_id
  route_table_id             = each.value.route_table_id
  transit_gateway_id         = data.aws_ec2_transit_gateway.transit_gateway.id
}

resource "aws_route" "vpc_peering_routes" {
  for_each = {
    for pair in setproduct(
      local.vpc_peering_routes,
      module.vpc.private_route_table_ids
    ) :
    "${pair[0].cidr_block}_${pair[1]}" => {
      peering_route  = pair[0]
      route_table_id = pair[1]
    }
  }
  route_table_id            = each.value.route_table_id
  destination_cidr_block    = each.value.peering_route.cidr_block
  vpc_peering_connection_id = each.value.peering_route.peering_connection
}
