# Hosted zones ===============================================================

resource "aws_route53_zone" "this" {
  for_each = var.zones

  name    = each.value.name
  comment = each.value.comment

  dynamic "vpc" {
    for_each = each.value.private ? toset(each.value.vpc_ids) : toset([])
    content {
      vpc_id = vpc.value
    }
  }

  tags = local.tags
}

# DNS records ================================================================

resource "aws_route53_record" "this" {
  for_each = var.records

  zone_id         = aws_route53_zone.this[each.value.zone_key].zone_id
  name            = each.value.name
  type            = each.value.type
  ttl             = each.value.alias == null ? each.value.ttl : null
  records         = each.value.alias == null ? each.value.records : null
  health_check_id = each.value.health_check_id
  set_identifier  = each.value.set_identifier
  allow_overwrite = each.value.allow_overwrite

  dynamic "alias" {
    for_each = each.value.alias != null ? [each.value.alias] : []
    content {
      name                   = alias.value.name
      zone_id                = alias.value.zone_id
      evaluate_target_health = alias.value.evaluate_target_health
    }
  }

  dynamic "weighted_routing_policy" {
    for_each = each.value.weight != null ? [each.value.weight] : []
    content {
      weight = weighted_routing_policy.value
    }
  }

  dynamic "latency_routing_policy" {
    for_each = each.value.latency_routing_policy != null ? [each.value.latency_routing_policy] : []
    content {
      region = latency_routing_policy.value.region
    }
  }

  dynamic "failover_routing_policy" {
    for_each = each.value.failover != null ? [each.value.failover] : []
    content {
      type = failover_routing_policy.value
    }
  }
}

# Health checks ==============================================================

resource "aws_route53_health_check" "this" {
  for_each = var.health_checks

  fqdn              = each.value.fqdn
  ip_address        = each.value.ip_address
  port              = each.value.port
  type              = each.value.type
  resource_path     = each.value.resource_path
  failure_threshold = each.value.failure_threshold
  request_interval  = each.value.request_interval

  tags = local.tags
}

# Resolver rules =============================================================

resource "aws_route53_resolver_rule" "this" {
  for_each = var.resolver_rules

  domain_name          = each.value.domain_name
  rule_type            = each.value.rule_type
  resolver_endpoint_id = each.value.resolver_endpoint_id

  dynamic "target_ip" {
    for_each = each.value.target_ips
    content {
      ip   = target_ip.value.ip
      port = target_ip.value.port
    }
  }

  tags = local.tags
}

resource "aws_route53_resolver_rule_association" "this" {
  for_each = local.resolver_rule_vpc_map

  resolver_rule_id = aws_route53_resolver_rule.this[each.value.rr_key].id
  vpc_id           = each.value.vpc_id
}
