################
# KMS — resolve AWS-managed S3 key
################

data "aws_kms_alias" "s3" {
  name = "alias/aws/s3"
}

################
# S3 — File Uploads
################

# Bucket for user-uploaded files via presigned URLs.
# The Coda server generates presigned PUT/GET URLs; the client uploads directly to S3.
module "s3_ows_coda_uploads" {
  count              = local.is_ephemeral ? 0 : 1
  source             = "git@github.com:theorchard/terraform-s3.git//modules/s3_bucket?ref=3.15.7"
  env                = var.environment
  bucket_name        = "ows-coda-uploads"
  application_family = var.application_family

  apply_server_side_encryption_by_default = {
    sse_algorithm     = "aws:kms"
    kms_master_key_id = data.aws_kms_alias.s3.target_key_arn
  }

  lifecycle_rules_abort_incomplete_multipart_upload_days = [
    {
      prefix  = ""
      days    = 7
      enabled = true
    }
  ]

  lifecycle_rules_options_current_version_transition = [
    {
      prefix        = ""
      days          = 30
      storage_class = "STANDARD_IA"
      enabled       = true
    },
    {
      prefix        = ""
      days          = 90
      storage_class = "GLACIER"
      enabled       = true
    },
    {
      prefix        = ""
      days          = 365
      storage_class = "DEEP_ARCHIVE"
      enabled       = true
    }
  ]

  block_public_access = true
}

################
# S3 — CORS
################

# Allow browser-based uploads/downloads from the Coda client via presigned URLs.
resource "aws_s3_bucket_cors_configuration" "ows_coda_uploads_cors" {
  count  = local.is_ephemeral ? 0 : 1
  bucket = module.s3_ows_coda_uploads[0].s3_bucket_name_output

  cors_rule {
    allowed_headers = ["*"]
    allowed_methods = ["PUT", "GET"]
    # Wildcard allows ephemeral env origins (e.g. qa-ows-coda-pr-42.theorchard.io).
    # Safe because: DNS zone is Terraform-managed (no rogue subdomains) and S3
    # access is via backend-signed presigned URLs, not browser credentials.
    allowed_origins = [
      "https://qa-ows-coda.theorchard.io",
      "https://qa-ows-coda-*.theorchard.io",
      "https://coda.qaorch.com",
    ]
    expose_headers  = ["ETag"]
    max_age_seconds = 3600
  }
}

################
# IAM — S3 access for Fargate task
################

data "aws_iam_policy_document" "ows_coda_uploads_policy_document" {
  # Allow the server to generate presigned PUT/GET URLs and manage objects.
  statement {
    effect = "Allow"

    actions = [
      "s3:GetObject",
      "s3:PutObject",
      "s3:DeleteObject",
    ]

    resources = [
      "${local.s3_arn}/*",
    ]
  }

  # Allow listing bucket contents (needed for management/cleanup).
  statement {
    effect = "Allow"

    actions = [
      "s3:GetBucketLocation",
      "s3:ListBucket",
    ]

    resources = [
      local.s3_arn,
    ]
  }

  # SSE-KMS: the Fargate task signs presigned URLs, so it needs KMS
  # permissions to encrypt (PUT) and decrypt (GET) objects.
  statement {
    effect = "Allow"

    actions = [
      "kms:GenerateDataKey",
      "kms:Decrypt",
    ]

    resources = [
      data.aws_kms_alias.s3.target_key_arn,
    ]
  }
}

resource "aws_iam_policy" "ows_coda_uploads_policy" {
  name        = "${var.environment}-${local.service_label}-uploads-policy"
  description = local.is_ephemeral ? "Ephemeral (${var.instance}): S3 uploads access for ows-coda" : "Allow ows-coda Fargate task to manage upload objects via presigned URLs"
  policy      = data.aws_iam_policy_document.ows_coda_uploads_policy_document.json
}

resource "aws_iam_role_policy_attachment" "ows_coda_uploads_policy_attachment" {
  role       = module.ows_coda_fargate_environment.fargate_task_iam_role_name
  policy_arn = aws_iam_policy.ows_coda_uploads_policy.arn
}

