data "aws_caller_identity" "current" {}

data "aws_acm_certificate" "certificate" {
  domain      = "${var.acm_certificate_cn}.${var.domain_name}"
  statuses    = ["ISSUED"]
  provider    = aws.primary
  most_recent = true
}

data "aws_s3_bucket" "bucket_primary" {
  bucket   = local.origin_primary_s3_bucket_name
  provider = aws.primary
}

data "aws_s3_bucket" "bucket_failover" {
  bucket   = local.origin_failover_s3_bucket_name
  provider = aws.failover
}

data "aws_wafv2_web_acl" "waf" {
  name  = local.waf_name
  scope = "CLOUDFRONT"
}

data "aws_cloudfront_response_headers_policy" "response_headers_policy" {
  count = var.response_headers_policy_enabled ? 1 : 0
  name  = local.response_headers_policy_name
}

# Requires corresponding change to S3 bucket policies
resource "aws_cloudfront_origin_access_identity" "origin_access_identity_primary" {
  comment = "${var.environment}-${var.brand}-${var.service_name}-primary-origin-access-identity"
}

resource "aws_cloudfront_origin_access_identity" "origin_access_identity_failover" {
  comment = "${var.environment}-${var.brand}-${var.service_name}-failover-origin-access-identity"
}

resource "aws_cloudfront_function" "viewer_request" {
  name    = "${var.environment}-${var.brand}-${var.service_name}-viewer-request"
  runtime = var.cloudfront_function_runtime
  comment = "${var.environment}-${var.brand}-${var.service_name}-viewer-request"
  publish = var.cloudfront_function_publish_changes_live
  code    = file("${local.cloudfront_function_file_path}")
}

resource "aws_cloudfront_distribution" "distribution" {
  # checkov:skip=CKV2_AWS_32:Cloudfront Distribution strict security headers policy. We have ORCD_AWS_3 through ORCD_AWS_9 custom policies to cover this.
  aliases             = local.aliases
  comment             = "${var.environment}-${var.brand}-${var.service_name}"
  enabled             = var.enabled
  is_ipv6_enabled     = var.is_ipv6_enabled
  http_version        = var.http_version
  price_class         = var.price_class
  web_acl_id          = data.aws_wafv2_web_acl.waf.arn
  wait_for_deployment = true
  default_root_object = var.default_root_object

  origin_group {
    origin_id = var.s3_origin_group_name

    failover_criteria {
      status_codes = var.failover_criteria_status_codes
    }

    member {
      origin_id = local.origin_primary_s3_bucket_name
    }

    member {
      origin_id = local.origin_failover_s3_bucket_name
    }
  }

  origin {
    domain_name = data.aws_s3_bucket.bucket_primary.bucket_domain_name
    origin_id   = local.origin_primary_s3_bucket_name
    origin_path = local.s3_origin_path

    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.origin_access_identity_primary.cloudfront_access_identity_path
    }
  }

  origin {
    domain_name = data.aws_s3_bucket.bucket_failover.bucket_domain_name
    origin_id   = local.origin_failover_s3_bucket_name
    origin_path = local.s3_origin_path

    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.origin_access_identity_failover.cloudfront_access_identity_path
    }
  }

  default_cache_behavior {
    allowed_methods            = var.allowed_methods
    cached_methods             = var.cached_methods
    default_ttl                = var.default_ttl
    min_ttl                    = var.minimum_ttl
    max_ttl                    = var.maximum_ttl
    compress                   = true
    target_origin_id           = var.s3_origin_group_name
    viewer_protocol_policy     = var.viewer_protocol_policy
    response_headers_policy_id = var.response_headers_policy_enabled ? data.aws_cloudfront_response_headers_policy.response_headers_policy.0.id : null

    forwarded_values {
      query_string = var.forward_query_strings_to_origin
      headers      = length(var.list_of_headers_to_forward) != 0 ? var.list_of_headers_to_forward : null

      cookies {
        forward           = var.forward_cookies_to_origin_setting
        whitelisted_names = var.forward_cookies_to_origin_setting == "whitelist" ? var.list_of_cookies_to_forward : null
      }
    }

    function_association {
      event_type   = "viewer-request"
      function_arn = aws_cloudfront_function.viewer_request.arn
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = var.restriction_type
      locations        = var.restriction_type != "none" ? var.restriction_list_of_countries : null
    }
  }

  viewer_certificate {
    acm_certificate_arn      = data.aws_acm_certificate.certificate.arn
    ssl_support_method       = "sni-only"
    minimum_protocol_version = var.minimum_protocol_version
  }

  logging_config {
    include_cookies = var.logging_include_cookies
    bucket          = local.logging_bucket_domain_name
    prefix          = "AWSLogs/${data.aws_caller_identity.current.account_id}/CloudfrontLogs/${var.environment}-${var.brand}-${var.service_name}/"
  }

  tags = local.combined_resource_tags
}
