# BIMI logo + PEM hosting: private S3 + CloudFront OAC
# Terraform >= 1.5, AWS provider >= 5.0
# Usage: terraform init && terraform apply -var="domain_name=bimi.example.com" -var="hosted_zone_id=ZXXXX"

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0"
    }
  }
}

variable "domain_name" {
  type        = string
  description = "Public hostname for logo/PEM (e.g. bimi.example.com)"
}

variable "hosted_zone_id" {
  type        = string
  description = "Route 53 hosted zone ID for domain_name"
  default     = ""
}

variable "price_class" {
  type    = string
  default = "PriceClass_100"
}

data "aws_caller_identity" "current" {}

resource "aws_s3_bucket" "bimi" {
  bucket_prefix = "bimi-assets-"
}

resource "aws_s3_bucket_public_access_block" "bimi" {
  bucket                  = aws_s3_bucket.bimi.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_server_side_encryption_configuration" "bimi" {
  bucket = aws_s3_bucket.bimi.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

resource "aws_cloudfront_origin_access_control" "bimi" {
  name                              = "bimi-oac"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

resource "aws_cloudfront_response_headers_policy" "bimi" {
  name = "bimi-security-headers"
  security_headers_config {
    content_type_options { override = true }
    frame_options {
      frame_option = "DENY"
      override     = true
    }
    referrer_policy {
      referrer_policy = "strict-origin-when-cross-origin"
      override        = true
    }
    strict_transport_security {
      access_control_max_age_sec = 31536000
      include_subdomains         = true
      preload                    = false
      override                   = true
    }
  }
}

resource "aws_cloudfront_distribution" "bimi" {
  enabled             = true
  is_ipv6_enabled     = true
  comment             = "BIMI logo and mark certificate"
  default_root_object = "logo.svg"
  price_class         = var.price_class
  aliases             = [var.domain_name]

  origin {
    domain_name              = aws_s3_bucket.bimi.bucket_regional_domain_name
    origin_id                = "bimi-s3"
    origin_access_control_id = aws_cloudfront_origin_access_control.bimi.id
  }

  default_cache_behavior {
    allowed_methods            = ["GET", "HEAD", "OPTIONS"]
    cached_methods             = ["GET", "HEAD"]
    target_origin_id           = "bimi-s3"
    viewer_protocol_policy     = "redirect-to-https"
    compress                   = true
    response_headers_policy_id = aws_cloudfront_response_headers_policy.bimi.id

    forwarded_values {
      query_string = false
      cookies { forward = "none" }
    }

    min_ttl     = 0
    default_ttl = 86400
    max_ttl     = 604800
  }

  restrictions {
    geo_restriction { restriction_type = "none" }
  }

  viewer_certificate {
    acm_certificate_arn      = aws_acm_certificate_validation.bimi.certificate_arn
    ssl_support_method       = "sni-only"
    minimum_protocol_version = "TLSv1.2_2021"
  }
}

resource "aws_acm_certificate" "bimi" {
  provider          = aws.us_east_1
  domain_name       = var.domain_name
  validation_method = "DNS"
}

provider "aws" {
  alias  = "us_east_1"
  region = "us-east-1"
}

resource "aws_route53_record" "cert_validation" {
  for_each = var.hosted_zone_id == "" ? {} : {
    for dvo in aws_acm_certificate.bimi.domain_validation_options : dvo.domain_name => {
      name  = dvo.resource_record_name
      type  = dvo.resource_record_type
      value = dvo.resource_record_value
    }
  }
  zone_id = var.hosted_zone_id
  name    = each.value.name
  type    = each.value.type
  records = [each.value.value]
  ttl     = 60
}

resource "aws_acm_certificate_validation" "bimi" {
  provider                = aws.us_east_1
  certificate_arn         = aws_acm_certificate.bimi.arn
  validation_record_fqdns = [for r in aws_route53_record.cert_validation : r.fqdn]
}

resource "aws_s3_bucket_policy" "bimi" {
  bucket = aws_s3_bucket.bimi.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid       = "AllowCloudFrontOAC"
      Effect    = "Allow"
      Principal = { Service = "cloudfront.amazonaws.com" }
      Action    = "s3:GetObject"
      Resource  = "${aws_s3_bucket.bimi.arn}/*"
      Condition = {
        StringEquals = {
          "AWS:SourceArn" = aws_cloudfront_distribution.bimi.arn
        }
      }
    }]
  })
}

resource "aws_route53_record" "alias" {
  count   = var.hosted_zone_id == "" ? 0 : 1
  zone_id = var.hosted_zone_id
  name    = var.domain_name
  type    = "A"
  alias {
    name                   = aws_cloudfront_distribution.bimi.domain_name
    zone_id                = aws_cloudfront_distribution.bimi.hosted_zone_id
    evaluate_target_health = false
  }
}

output "bucket_name" { value = aws_s3_bucket.bimi.bucket }
output "distribution_id" { value = aws_cloudfront_distribution.bimi.id }
output "logo_url" { value = "https://${var.domain_name}/logo.svg" }
output "pem_url" { value = "https://${var.domain_name}/certificate.pem" }
