resource "aws_s3_bucket" "input_assets_bucket" {
  bucket              = "${var.environment}-${var.input_bucket_name}"
  acl                 = "private"
  acceleration_status = "Enabled"

  dynamic "cors_rule" {
    for_each = var.input_bucket_cors
    content {
      allowed_headers = cors_rule.value.allowed_headers
      allowed_methods = cors_rule.value.allowed_methods
      allowed_origins = cors_rule.value.allowed_origins
      expose_headers  = cors_rule.value.expose_headers
      max_age_seconds = cors_rule.value.max_age_seconds
    }
  }

  dynamic "logging" {
    for_each = var.logging_target_bucket
    content {
      target_bucket = logging.value
      target_prefix = "${var.environment}-${var.input_bucket_name}"
    }
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

resource "aws_s3_bucket" "output_bucket" {
  bucket              = "${var.environment}-${var.output_bucket_name}"
  acl                 = "private"
  acceleration_status = "Enabled"

  dynamic "cors_rule" {
    for_each = var.output_bucket_cors
    content {
      allowed_headers = cors_rule.value.allowed_headers
      allowed_methods = cors_rule.value.allowed_methods
      allowed_origins = cors_rule.value.allowed_origins
      expose_headers  = cors_rule.value.expose_headers
      max_age_seconds = cors_rule.value.max_age_seconds
    }
  }

  dynamic "logging" {
    for_each = var.logging_target_bucket
    content {
      target_bucket = logging.value
      target_prefix = "${var.environment}-${var.output_bucket_name}"
    }
  }


  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

resource "aws_cloudfront_origin_access_identity" "output_bucket_origin_access_identity" {
  comment = "access-identity-${aws_s3_bucket.output_bucket.id}.s3.amazonaws.com"
}

data "aws_iam_policy_document" "output_bucket_policy" {
  statement {
    actions   = ["s3:GetObject"]
    resources = ["arn:aws:s3:::${aws_s3_bucket.output_bucket.id}/*"]

    principals {
      type        = "AWS"
      identifiers = [aws_cloudfront_origin_access_identity.output_bucket_origin_access_identity.iam_arn]
    }
  }
}

resource "aws_s3_bucket_policy" "podcast_output_bucket_policy" {
  policy = data.aws_iam_policy_document.output_bucket_policy.json
  bucket = aws_s3_bucket.output_bucket.id
}

resource "aws_cloudfront_distribution" "output_assets_cdn" {
  enabled         = true
  is_ipv6_enabled = true
  comment         = "Distribution for podcast Megaphone assets ${var.output_assets_domain}"
  price_class     = "PriceClass_All"
  http_version    = "http2"
  aliases         = [var.output_assets_domain]

  origin {
    domain_name = "${aws_s3_bucket.output_bucket.id}.s3.amazonaws.com"
    origin_id   = "S3-${aws_s3_bucket.output_bucket.id}"

    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.output_bucket_origin_access_identity.cloudfront_access_identity_path
    }
  }

  default_cache_behavior {
    viewer_protocol_policy = "https-only"
    compress               = false
    allowed_methods        = ["GET", "HEAD", "OPTIONS"]
    cached_methods         = ["GET", "HEAD"]

    target_origin_id = "S3-${aws_s3_bucket.output_bucket.id}"
    min_ttl          = var.cdn_min_ttl
    default_ttl      = var.cdn_default_ttl
    max_ttl          = var.cdn_max_ttl

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
      headers = [
        "Origin",
        "Access-Control-Request-Headers",
        "Access-Control-Request-Method",
      ]
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  logging_config {
    include_cookies = false
    bucket          = var.cloudfront_logs_bucket
  }

  viewer_certificate {
    acm_certificate_arn      = var.output_assets_cdn_certificate_arn
    ssl_support_method       = "sni-only"
    minimum_protocol_version = "TLSv1.2_2018"
  }
}

data "aws_iam_policy_document" "output_bucket_readonly_policy" {
  statement {
    actions = [
      "s3:ListBucket",
    ]

    effect    = "Allow"
    resources = [aws_s3_bucket.output_bucket.arn]
  }

  statement {
    actions = [
      "s3:GetObject",
      "s3:HeadObject",
    ]

    effect    = "Allow"
    resources = ["${aws_s3_bucket.output_bucket.arn}/*"]
  }
}

resource "aws_iam_policy" "output_bucket_readonly_policy" {
  name        = "S3-${aws_s3_bucket.output_bucket.id}-RO"
  description = "Read only access policy for output bucket"
  policy      = data.aws_iam_policy_document.output_bucket_readonly_policy.json
}
