data "google_secret_manager_secret" "hec_encrypted_token" {
  secret_id = "dev-gsirt-splunk-logs-hec-token" # GCP secrets manager only supports - and _.
}

data "google_secret_manager_secret_version" "hec_encrypted_token_version" {
  secret = data.google_secret_manager_secret.hec_encrypted_token.id
}

# TBD this is exposing token in plaintext in the terraform state
#resource "google_kms_secret_ciphertext" "hec_encrypted_token" {
#  crypto_key = var.splunk_hec_crypto_key
#  plaintext  = var.splunk_hec_token
#}

resource "google_service_account" "dataflow_service_account" {
  account_id   = "gsirt-dataflow-service-account"
  display_name = "GSIRT Dataflow Service Account"
}

resource "google_project_iam_member" "roles_dataflow_admin" {
  project = var.project
  role    = "roles/dataflow.admin"

  member = "serviceAccount:${google_service_account.dataflow_service_account.email}"
}

resource "google_project_iam_member" "roles_dataflow_developer" {
  #checkov:skip=CKV_GCP_49
  project = var.project
  role    = "roles/dataflow.developer"

  member = "serviceAccount:${google_service_account.dataflow_service_account.email}"
}

resource "google_project_iam_member" "roles_dataflow_worker" {
  project = var.project
  role    = "roles/dataflow.worker"

  member = "serviceAccount:${google_service_account.dataflow_service_account.email}"
}

resource "google_project_iam_member" "roles_dataflow_viewer" {
  project = var.project
  role    = "roles/dataflow.viewer"

  member = "serviceAccount:${google_service_account.dataflow_service_account.email}"
}

resource "google_project_iam_member" "roles_dataflow_monitoring_metric_writer" {
  project = var.project
  role    = "roles/monitoring.metricWriter"

  member = "serviceAccount:${google_service_account.dataflow_service_account.email}"
}

# TBD this is exposing token in plaintext in the terraform state
#resource "google_kms_crypto_key_iam_binding" "splunk_hec_crypto_key" {
#  crypto_key_id = var.splunk_hec_crypto_key
#  role          = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
#
#  members = [
#    "serviceAccount:${google_service_account.dataflow_service_account.email}",
#  ]
#}
#
#resource "google_kms_key_ring_iam_binding" "splunk_hec_keyring_service_account" {
#  key_ring_id = var.splunk_hec_keyring
#  role        = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
#
#  members = [
#    "serviceAccount:${google_service_account.dataflow_service_account.email}",
#  ]
#}

resource "google_pubsub_topic" "dataflow_deadletter_pubsub_topic" {
  #checkov:skip=CKV_GCP_83:Introducing CMK's to the cloud function introduces complexity in the automation process that would need to be built in
  name = local.dataflow_output_deadletter_topic_name
}

resource "google_pubsub_subscription" "dataflow_deadletter_pubsub_sub" {
  name  = local.dataflow_output_deadletter_sub_name
  topic = google_pubsub_topic.dataflow_deadletter_pubsub_topic.name

  # messages retained for 7 days (max)
  message_retention_duration = "604800s"

  # subscription never expires
  expiration_policy {
    ttl = ""
  }
}

resource "google_pubsub_topic_iam_member" "deadletter_publisher" {
  topic = google_pubsub_topic.dataflow_deadletter_pubsub_topic.name
  role  = "roles/pubsub.publisher"

  member = "serviceAccount:${google_service_account.dataflow_service_account.email}"
}

resource "google_pubsub_topic_iam_member" "deadletter_viewer" {
  topic = google_pubsub_topic.dataflow_deadletter_pubsub_topic.name
  role  = "roles/pubsub.viewer"

  member = "serviceAccount:${google_service_account.dataflow_service_account.email}"
}

resource "google_storage_bucket" "dataflow_job_temp_bucket" {
  #checkov:skip=CKV_GCP_62
  #checkov:skip=CKV_GCP_29:This is either one option or another (granular bucket ACL policies, or uniform bucket access) not both. We have granular ACLs defined via TF on the buckets we use
  #checkov:skip=CKV_GCP_78:The cloud storage account is used for temp storage the function needs while executing, there is not persistent storage.
  name          = local.dataflow_temporary_gcs_bucket_name
  location      = var.region
  storage_class = "REGIONAL"
}

resource "google_storage_bucket_object" "dataflow_job_temp_object" {
  name    = local.dataflow_temporary_gcs_bucket_path
  content = "Placeholder for Dataflow to write temporary files"
  bucket  = google_storage_bucket.dataflow_job_temp_bucket.name
}

resource "google_storage_bucket" "dataflow_udf_bucket" {
  #checkov:skip=CKV_GCP_62
  #checkov:skip=CKV_GCP_29:This is either one option or another (granular bucket ACL policies, or uniform bucket access) not both. We have granular ACLs defined via TF on the buckets we use
  #checkov:skip=CKV_GCP_78:The cloud storage account is used for temp storage the function needs while executing, there is not persistent storage.
  name          = local.dataflow_udf_bucket_name
  location      = var.region
  storage_class = "REGIONAL"
}

resource "google_storage_bucket_object" "dataflow_udf_object" {
  name   = local.dataflow_udf_bucket_object_name
  source = "dataflow_udf_messages_replay.js"
  bucket = google_storage_bucket.dataflow_udf_bucket.name
}

resource "google_dataflow_job" "dataflow_job" {
  #checkov:skip=CKV_GCP_90:Introducing CMK's to the cloud function introduces complexity in the automation process that would need to be built in
  name                  = local.dataflow_main_job_name
  template_gcs_path     = local.dataflow_splunk_template_gcs_path
  temp_gcs_location     = "gs://${local.dataflow_temporary_gcs_bucket_name}/${local.dataflow_temporary_gcs_bucket_path}"
  machine_type          = var.dataflow_job_machine_type
  max_workers           = var.dataflow_job_machine_count
  service_account_email = google_service_account.dataflow_service_account.email
  parameters = {
    inputSubscription     = google_pubsub_subscription.dataflow_input_pubsub_subscription.id
    outputDeadletterTopic = google_pubsub_topic.dataflow_deadletter_pubsub_topic.id
    url                   = var.splunk_hec_url
    token                 = data.google_secret_manager_secret_version.hec_encrypted_token_version.secret_data
    #tokenKMSEncryptionKey               = var.splunk_hec_crypto_key
    parallelism                         = var.dataflow_job_parallelism
    batchCount                          = var.dataflow_job_batch_count
    includePubsubMessage                = local.dataflow_job_include_pubsub_message
    disableCertificateValidation        = var.dataflow_job_disable_certificate_validation
    javascriptTextTransformGcsPath      = "gs://${local.dataflow_udf_bucket_name}/${local.dataflow_udf_bucket_object_name}"
    javascriptTextTransformFunctionName = var.dataflow_job_udf_function_name
  }
  region           = var.region
  network          = var.network
  subnetwork       = "regions/${var.region}/subnetworks/${local.subnet_name}"
  ip_configuration = "WORKER_IP_PRIVATE"
  on_delete        = "cancel"

  depends_on = [
    google_compute_subnetwork.splunk_subnet
  ]
}
