locals {
  google_required_services = toset([
    "storage.googleapis.com",
  ])

  release_storage_buckets = {
    releases = {
      name        = var.google_release_bucket_name
      description = "Burrow release artifacts"
      public      = var.google_release_public_read
    }
    packages = {
      name        = var.google_package_bucket_name
      description = "Burrow signed package repositories"
      public      = var.google_package_public_read
    }
    nix-cache = {
      name        = var.google_nix_cache_bucket_name
      description = "Burrow Nix cache backups"
      public      = var.google_nix_cache_public_read
    }
  }

  release_storage_writer_members = setunion(
    var.google_release_extra_writer_members,
    toset(["serviceAccount:${var.google_runner_service_account_email}"]),
  )

  release_storage_writer_grants = var.manage_google ? {
    for grant in flatten([
      for bucket_key in keys(local.release_storage_buckets) : [
        for member in local.release_storage_writer_members : {
          id         = "${bucket_key}|${member}"
          bucket_key = bucket_key
          member     = member
        }
      ]
    ]) : grant.id => grant
  } : {}

  release_storage_public_grants = var.manage_google ? {
    for bucket_key, bucket in local.release_storage_buckets : bucket_key => bucket
    if bucket.public
  } : {}
}

resource "google_project_service" "release_storage" {
  for_each = var.manage_google ? local.google_required_services : toset([])

  project            = var.google_project_id
  service            = each.value
  disable_on_destroy = false
}

resource "google_storage_bucket" "release_storage" {
  for_each = var.manage_google ? local.release_storage_buckets : {}

  project                     = var.google_project_id
  name                        = each.value.name
  location                    = var.google_storage_location
  uniform_bucket_level_access = true
  public_access_prevention    = each.value.public ? "inherited" : "enforced"
  force_destroy               = false

  labels = merge(
    {
      project    = "burrow"
      component  = "release-storage"
      managed_by = "opentofu"
      bucket     = each.key
    },
    var.tags,
  )

  versioning {
    enabled = true
  }

  cors {
    origin          = var.google_storage_cors_origins
    method          = ["GET", "HEAD", "OPTIONS"]
    response_header = ["Content-Type", "Content-Length", "ETag", "Cache-Control"]
    max_age_seconds = 3600
  }

  lifecycle_rule {
    condition {
      age                   = 30
      with_state            = "ARCHIVED"
      num_newer_versions    = 5
      matches_storage_class = ["STANDARD"]
    }

    action {
      type = "Delete"
    }
  }

  depends_on = [google_project_service.release_storage]
}

resource "google_storage_bucket_iam_member" "release_storage_public_viewer" {
  for_each = local.release_storage_public_grants

  bucket = google_storage_bucket.release_storage[each.key].name
  role   = "roles/storage.objectViewer"
  member = "allUsers"
}

resource "google_storage_bucket_iam_member" "release_storage_writer" {
  for_each = local.release_storage_writer_grants

  bucket = google_storage_bucket.release_storage[each.value.bucket_key].name
  role   = "roles/storage.objectAdmin"
  member = each.value.member
}
