# =============================================================================
# S3 buckets — o11y backups, vmcluster shared storage, loki, ds access logs.
# Bucket names and policies are ported from the infra / basic-addon scripts.
# Versioning stays off and force_destroy stays false: buckets are emptied by
# null_resource.bucket_flush before Terraform deletes them.
# =============================================================================

resource "aws_s3_bucket" "o11y_backups" {
  bucket = "o11y-${var.env}-${var.logical_region_name}-backups"
  tags   = local.common_tags
}

resource "aws_s3_bucket" "shared" {
  bucket = "o11y-${var.env}-shared-${var.logical_region_name}"
  tags   = local.common_tags
}

resource "aws_s3_bucket" "loki" {
  bucket = "loki-${var.env}-${var.logical_region_name}-o11y"
  tags   = local.common_tags
}

# Same lifecycle as lifecycle.json in the old dataplane script
resource "aws_s3_bucket_lifecycle_configuration" "loki" {
  bucket = aws_s3_bucket.loki.id

  rule {
    id     = "delete_90_days"
    status = "Enabled"

    filter {
      prefix = "fake/"
    }

    expiration {
      days = 91
    }
  }
}

resource "aws_s3_bucket" "ds_logs" {
  bucket = "${local.cluster_name}-ds-logs"
  tags   = local.common_tags
}

resource "aws_s3_bucket_public_access_block" "ds_logs" {
  bucket = aws_s3_bucket.ds_logs.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# ELB access-log delivery policy, ported from the basic/addon script. The
# elb_account_id statement is added only when the variable is set (same
# condition as the script).
resource "aws_s3_bucket_policy" "ds_logs" {
  bucket = aws_s3_bucket.ds_logs.id
  policy = jsonencode({
    Version = "2012-10-17"
    Id      = "AWSConsole-AccessLogs-Policy-1628794925198"
    Statement = concat(
      var.elb_account_id != null ? [
        {
          Sid    = "AWSConsoleStmt-1628794925198"
          Effect = "Allow"
          Principal = {
            AWS = "arn:aws:iam::${var.elb_account_id}:root"
          }
          Action   = "s3:PutObject"
          Resource = "arn:aws:s3:::${aws_s3_bucket.ds_logs.bucket}/*"
        }
      ] : [],
      [
        {
          Sid    = "AWSConsoleStmt-regions-after-202208"
          Effect = "Allow"
          Principal = {
            Service = "logdelivery.elasticloadbalancing.amazonaws.com"
          }
          Action   = "s3:PutObject"
          Resource = "arn:aws:s3:::${aws_s3_bucket.ds_logs.bucket}/*"
        },
        {
          Sid    = "AWSLogDeliveryWrite"
          Effect = "Allow"
          Principal = {
            Service = "delivery.logs.amazonaws.com"
          }
          Action   = "s3:PutObject"
          Resource = "arn:aws:s3:::${aws_s3_bucket.ds_logs.bucket}/*"
          Condition = {
            StringEquals = {
              "s3:x-amz-acl" = "bucket-owner-full-control"
            }
          }
        },
        {
          Sid    = "AWSLogDeliveryAclCheck"
          Effect = "Allow"
          Principal = {
            Service = "delivery.logs.amazonaws.com"
          }
          Action   = "s3:GetBucketAcl"
          Resource = "arn:aws:s3:::${aws_s3_bucket.ds_logs.bucket}"
        }
      ]
    )
  })
}

# =============================================================================
# Bucket flush on destroy
#
# AWS refuses to delete a non-empty bucket. This no-op-on-create resource sits
# downstream of the buckets: on destroy its provisioner runs BEFORE the bucket
# deletions (reverse dependency order) and empties each bucket, so the
# aws_s3_bucket deletions below always succeed.
# =============================================================================

resource "null_resource" "bucket_flush" {
  depends_on = [
    aws_s3_bucket.o11y_backups,
    aws_s3_bucket.shared,
    aws_s3_bucket.loki,
    aws_s3_bucket.ds_logs,
  ]

  triggers = {
    aws_profile = local.o11y_account
    aws_region  = var.aws_region
    buckets = join(" ", [
      "o11y-${var.env}-${var.logical_region_name}-backups",
      "o11y-${var.env}-shared-${var.logical_region_name}",
      "loki-${var.env}-${var.logical_region_name}-o11y",
      "${local.cluster_name}-ds-logs",
    ])
  }

  provisioner "local-exec" {
    when        = create
    interpreter = ["bash", "-c"]
    command     = "echo 'bucket_flush: no-op on create'"
  }

  provisioner "local-exec" {
    when        = destroy
    interpreter = ["bash", "-c"]
    command     = <<-EOT
      set -uo pipefail

      for bucket in ${self.triggers.buckets}; do
        if aws s3api head-bucket --bucket "$bucket" \
          --profile ${self.triggers.aws_profile} --region ${self.triggers.aws_region} 2>/dev/null; then
          echo "Flushing bucket $bucket ..."
          aws s3 rm "s3://$bucket" --recursive \
            --profile ${self.triggers.aws_profile} --region ${self.triggers.aws_region}
        else
          echo "Bucket $bucket does not exist, skipping"
        fi
      done
    EOT
  }
}
