# Copyright 2021 Google LLC
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#     https://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

provider "aws" {
  region = "us-east-1" # AWS provider here is used for atlantis to terraform GCP resources.
}

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "4.21.0"
    }
  }
}

terraform {
  backend "s3" {
    bucket  = "orcd-terraform-state"
    key     = "prod/gcp/gsirt-splunk-logs/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

data "aws_secretsmanager_secret" "gsirt_splunk_logs" {
  name = "${var.environment}/${var.service_name}/gcp_key"
}

data "aws_secretsmanager_secret_version" "gsirt_splunk_logs_key" {
  secret_id = data.aws_secretsmanager_secret.gsirt_splunk_logs.id
}

provider "google" {
  credentials = data.aws_secretsmanager_secret_version.gsirt_splunk_logs_key.secret_string
  project     = var.project
  region      = var.region
}

# Generate new random hex to be used for bucket name
resource "random_id" "bucket_suffix" {
  byte_length = 4
}

# Generate new random id each time we switch to a new template version id,
# to be used for pipeline job name to force job replacement vs in-place update
resource "random_id" "dataflow_job_instance" {
  byte_length = 2
  keepers = {
    dataflow_template_version = var.dataflow_template_version
  }
}

locals {
  dataflow_temporary_gcs_bucket_name = "${var.project}-${var.dataflow_job_name}-${random_id.bucket_suffix.hex}"
  dataflow_temporary_gcs_bucket_path = "tmp/"
  dataflow_udf_bucket_name           = "${var.project}-${var.dataflow_job_name}-${random_id.bucket_suffix.hex}2"
  dataflow_udf_bucket_object_name    = "dataflow_udf_messages_replay.js"

  dataflow_splunk_template_gcs_path = "gs://dataflow-templates/${var.dataflow_template_version}/Cloud_PubSub_to_Splunk"
  dataflow_pubsub_template_gcs_path = "gs://dataflow-templates/${var.dataflow_template_version}/Cloud_PubSub_to_Cloud_PubSub"

  subnet_name                = coalesce(var.subnet, "${var.network}-${var.region}")
  project_log_sink_name      = "${var.dataflow_job_name}-project-log-sink"
  organization_log_sink_name = "${var.dataflow_job_name}-organization-log-sink-${random_id.dataflow_job_instance.hex}"

  dataflow_main_job_name   = "${var.dataflow_job_name}-main-${random_id.dataflow_job_instance.hex}"
  dataflow_replay_job_name = "${var.dataflow_job_name}-replay-${random_id.dataflow_job_instance.hex}"

  dataflow_input_topic_name             = "${var.dataflow_job_name}-input-topic"
  dataflow_input_subscription_name      = "${var.dataflow_job_name}-input-subscription"
  dataflow_output_deadletter_topic_name = "${var.dataflow_job_name}-deadletter-topic"
  dataflow_output_deadletter_sub_name   = "${var.dataflow_job_name}-deadletter-subscription"

  # dataflow job parameters (not externalized for this project)
  dataflow_job_include_pubsub_message = true
}

resource "google_pubsub_topic" "dataflow_input_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_input_topic_name
}

resource "google_pubsub_subscription" "dataflow_input_pubsub_subscription" {
  name  = local.dataflow_input_subscription_name
  topic = google_pubsub_topic.dataflow_input_pubsub_topic.name

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

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

resource "google_pubsub_subscription_iam_member" "subscriber" {
  subscription = google_pubsub_subscription.dataflow_input_pubsub_subscription.name
  role         = "roles/pubsub.subscriber"

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

resource "google_pubsub_subscription_iam_member" "viewer" {
  subscription = google_pubsub_subscription.dataflow_input_pubsub_subscription.name
  role         = "roles/pubsub.viewer"

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

resource "google_logging_organization_sink" "organization_log_sink" {
  name        = local.organization_log_sink_name
  org_id      = var.organization_id
  destination = "pubsub.googleapis.com/projects/${var.project}/topics/${google_pubsub_topic.dataflow_input_pubsub_topic.name}"
  filter      = var.log_filter

  include_children = "true"
}

resource "google_pubsub_topic_iam_binding" "pubsub_iam_binding" {
  project = google_pubsub_topic.dataflow_input_pubsub_topic.project
  topic   = google_pubsub_topic.dataflow_input_pubsub_topic.name
  role    = "roles/pubsub.publisher"
  members = [
    google_logging_organization_sink.organization_log_sink.writer_identity,
  ]
}
