# Cloud Monitoring -> authenticated Pub/Sub push -> signed Feishu bot.
# Secret values are populated out of band and never enter Terraform state.
data "google_project" "alerts" {
  project_id = var.project_id
}

resource "google_project_service" "alert_apis" {
  for_each           = toset(["pubsub.googleapis.com", "monitoring.googleapis.com"])
  project            = var.project_id
  service            = each.key
  disable_on_destroy = false
}

resource "google_secret_manager_secret" "feishu_alert" {
  for_each  = toset(["webhook", "signing-secret"])
  project   = var.project_id
  secret_id = "pingcap-alert-feishu-${each.key}"
  replication {
    auto {}
  }
}

resource "google_service_account" "alert_relay" {
  project      = var.project_id
  account_id   = "pingcap-alert-relay"
  display_name = "Pipeline Feishu alert relay"
}

resource "google_service_account" "alert_push" {
  project      = var.project_id
  account_id   = "pingcap-alert-push"
  display_name = "Authenticated PubSub delivery to pipeline alert relay"
}

resource "google_secret_manager_secret_iam_member" "alert_relay" {
  for_each  = google_secret_manager_secret.feishu_alert
  project   = var.project_id
  secret_id = each.value.secret_id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.alert_relay.email}"
}

resource "google_storage_bucket" "alert_receipts" {
  project                     = var.project_id
  name                        = "${var.project_id}-pingcap-alert-receipts"
  location                    = var.region
  uniform_bucket_level_access = true
  public_access_prevention    = "enforced"
  lifecycle_rule {
    condition { age = 7 }
    action { type = "Delete" }
  }
}

resource "google_storage_bucket_iam_member" "alert_receipts" {
  bucket = google_storage_bucket.alert_receipts.name
  role   = "roles/storage.objectUser"
  member = "serviceAccount:${google_service_account.alert_relay.email}"
}

resource "google_cloud_run_v2_service" "alert_relay" {
  project             = var.project_id
  name                = "pingcap-alert-relay"
  location            = var.region
  deletion_protection = false
  ingress             = "INGRESS_TRAFFIC_ALL"
  template {
    service_account                  = google_service_account.alert_relay.email
    timeout                          = "30s"
    max_instance_request_concurrency = 1
    scaling { max_instance_count = 1 }
    containers {
      image   = local.pipeline_image
      command = ["pingcap-alert-relay"]
      ports { container_port = 8080 }
      resources {
        limits = { cpu = "1", memory = "512Mi" }
      }
      env {
        name  = "ALERT_PROJECT"
        value = var.project_id
      }
      env {
        name  = "ALERT_RECEIPT_BUCKET"
        value = google_storage_bucket.alert_receipts.name
      }
      env {
        name = "FEISHU_FAILURE_WEBHOOK_URL"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.feishu_alert["webhook"].secret_id
            version = "latest"
          }
        }
      }
      env {
        name = "FEISHU_FAILURE_SIGNING_SECRET"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.feishu_alert["signing-secret"].secret_id
            version = "latest"
          }
        }
      }
    }
  }
  depends_on = [google_secret_manager_secret_iam_member.alert_relay, google_storage_bucket_iam_member.alert_receipts]
}

resource "google_cloud_run_v2_service_iam_member" "alert_push" {
  project  = var.project_id
  location = var.region
  name     = google_cloud_run_v2_service.alert_relay.name
  role     = "roles/run.invoker"
  member   = "serviceAccount:${google_service_account.alert_push.email}"
}

resource "google_service_account_iam_member" "alert_push_token" {
  service_account_id = google_service_account.alert_push.name
  role               = "roles/iam.serviceAccountTokenCreator"
  member             = "serviceAccount:service-${data.google_project.alerts.number}@gcp-sa-pubsub.iam.gserviceaccount.com"
  depends_on         = [google_project_service.alert_apis]
}

resource "google_service_account_iam_member" "deployer_act_as_alert_relay" {
  service_account_id = google_service_account.alert_relay.name
  role               = "roles/iam.serviceAccountUser"
  member             = "serviceAccount:${google_service_account.deployer.email}"
}

resource "google_pubsub_topic" "pipeline_alerts" {
  project    = var.project_id
  name       = "pingcap-pipeline-alerts"
  depends_on = [google_project_service.alert_apis]
}

resource "google_monitoring_notification_channel" "feishu_alerts" {
  project      = var.project_id
  display_name = "Pipeline failures to signed Feishu bot"
  type         = "pubsub"
  labels       = { topic = google_pubsub_topic.pipeline_alerts.id }
}

resource "google_pubsub_topic_iam_member" "monitoring_alert_publisher" {
  project = var.project_id
  topic   = google_pubsub_topic.pipeline_alerts.name
  role    = "roles/pubsub.publisher"
  member  = "serviceAccount:service-${data.google_project.alerts.number}@gcp-sa-monitoring-notification.iam.gserviceaccount.com"
  # The first Pub/Sub channel creates the Monitoring notification service agent.
  depends_on = [google_monitoring_notification_channel.feishu_alerts]
}

resource "google_pubsub_subscription" "feishu_alerts" {
  project                    = var.project_id
  name                       = "pingcap-pipeline-alerts-feishu"
  topic                      = google_pubsub_topic.pipeline_alerts.id
  ack_deadline_seconds       = 30
  message_retention_duration = "86400s"
  expiration_policy { ttl = "" }
  retry_policy {
    minimum_backoff = "60s"
    maximum_backoff = "600s"
  }
  push_config {
    push_endpoint = "${google_cloud_run_v2_service.alert_relay.uri}/pubsub"
    oidc_token {
      service_account_email = google_service_account.alert_push.email
      audience              = google_cloud_run_v2_service.alert_relay.uri
    }
  }
  depends_on = [google_cloud_run_v2_service_iam_member.alert_push, google_service_account_iam_member.alert_push_token]
}
