# This is an independent NexusCRM API run/release unit. It is absent by
# default and the ordinary inbound main deploy allowlist does not update it.

locals {
  netsuite_revenue_api_secrets = {
    consumer_key    = "pingcap-netsuite-revenue-tba-consumer-key"
    consumer_secret = "pingcap-netsuite-revenue-tba-consumer-secret"
    token_key       = "pingcap-netsuite-revenue-tba-token-key"
    token_secret    = "pingcap-netsuite-revenue-tba-token-secret"
    client_id       = "pingcap-netsuite-revenue-nexuscrm-client-id"
    client_secret   = "pingcap-netsuite-revenue-nexuscrm-client-secret"
  }
}

resource "google_storage_bucket" "netsuite_revenue_candidate" {
  count = var.enable_netsuite_revenue_to_nexuscrm ? 1 : 0

  project                     = var.project_id
  name                        = "${var.project_id}-netsuite-revenue-candidate"
  location                    = var.region
  uniform_bucket_level_access = true
  public_access_prevention    = "enforced"
  labels                      = merge(var.labels, { component = "netsuite-revenue-api" })

  lifecycle_rule {
    action { type = "Delete" }
    condition {
      age            = 365
      matches_prefix = ["runs/"]
    }
  }

  depends_on = [google_project_service.required]
}

resource "google_service_account" "netsuite_revenue_runtime" {
  count = var.enable_netsuite_revenue_to_nexuscrm ? 1 : 0

  project      = var.project_id
  account_id   = "pc-ns-revenue-api"
  display_name = "NetSuite revenue NexusCRM API runtime"

  depends_on = [google_project_service.required]
}

resource "google_service_account" "netsuite_revenue_scheduler" {
  count = var.enable_netsuite_revenue_to_nexuscrm ? 1 : 0

  project      = var.project_id
  account_id   = "pc-ns-revenue-scheduler"
  display_name = "NetSuite revenue scheduler invoker"

  depends_on = [google_project_service.required]
}

resource "google_secret_manager_secret" "netsuite_revenue_api" {
  for_each = var.enable_netsuite_revenue_to_nexuscrm ? local.netsuite_revenue_api_secrets : {}

  project   = var.project_id
  secret_id = each.value

  replication {
    auto {}
  }

  depends_on = [google_project_service.required]
}

resource "google_secret_manager_secret_iam_member" "netsuite_revenue_api_accessor" {
  for_each = google_secret_manager_secret.netsuite_revenue_api

  project   = var.project_id
  secret_id = each.value.secret_id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.netsuite_revenue_runtime[0].email}"
}

resource "google_storage_bucket_iam_member" "netsuite_revenue_runtime_candidate_writer" {
  count = var.enable_netsuite_revenue_to_nexuscrm ? 1 : 0

  bucket = google_storage_bucket.netsuite_revenue_candidate[0].name
  role   = "roles/storage.objectAdmin"
  member = "serviceAccount:${google_service_account.netsuite_revenue_runtime[0].email}"
}

resource "google_cloud_run_v2_job" "netsuite_revenue_to_nexuscrm" {
  count = var.enable_netsuite_revenue_to_nexuscrm ? 1 : 0

  project             = var.project_id
  name                = "pingcap-netsuite-revenue-to-nexuscrm"
  location            = var.region
  labels              = merge(var.labels, { component = "netsuite-revenue-api" })
  deletion_protection = false

  lifecycle {
    # A separate manually authorized deploy target supplies an immutable
    # digest. The ordinary inbound main deploy never updates this Job.
    ignore_changes = [template[0].template[0].containers[0].image]
    precondition {
      condition     = can(regex("@sha256:[0-9a-f]{64}$", var.netsuite_revenue_pipeline_image))
      error_message = "netsuite_revenue_pipeline_image must be a separately approved immutable image digest."
    }
    precondition {
      condition     = length(trimspace(var.netsuite_revenue_posting_period_id)) > 0
      error_message = "An enabled NexusCRM API Job requires an explicit posting period."
    }
  }

  template {
    template {
      service_account = google_service_account.netsuite_revenue_runtime[0].email
      timeout         = "3600s"
      max_retries     = 0

      containers {
        image = var.netsuite_revenue_pipeline_image
        # No --validate-only or --commit is present. This provisioned job only
        # freezes an immutable source candidate; all CRM API reads/writes need
        # separately approved invocation arguments and commit gates.
        args = [
          "netsuite-revenue-to-nexuscrm",
          "--posting-period-id",
          var.netsuite_revenue_posting_period_id,
          "--live-source",
        ]

        resources {
          limits = { cpu = "1", memory = "1Gi" }
        }

        env {
          name  = "GOOGLE_CLOUD_PROJECT"
          value = var.project_id
        }
        env {
          name  = "NETSUITE_REVENUE_RESTLET_URL"
          value = var.netsuite_revenue_restlet_url
        }
        env {
          name  = "NETSUITE_REVENUE_CANDIDATE_GCS_URI"
          value = "gs://${google_storage_bucket.netsuite_revenue_candidate[0].name}/runs"
        }
        env {
          name  = "NEXUSCRM_REVENUE_BASE_URL"
          value = var.netsuite_revenue_nexuscrm_base_url
        }

        env {
          name = "NETSUITE_REVENUE_TBA_CONSUMER_KEY"
          value_source {
            secret_key_ref {
              secret  = google_secret_manager_secret.netsuite_revenue_api["consumer_key"].secret_id
              version = "latest"
            }
          }
        }
        env {
          name = "NETSUITE_REVENUE_TBA_CONSUMER_SECRET"
          value_source {
            secret_key_ref {
              secret  = google_secret_manager_secret.netsuite_revenue_api["consumer_secret"].secret_id
              version = "latest"
            }
          }
        }
        env {
          name = "NETSUITE_REVENUE_TBA_TOKEN_KEY"
          value_source {
            secret_key_ref {
              secret  = google_secret_manager_secret.netsuite_revenue_api["token_key"].secret_id
              version = "latest"
            }
          }
        }
        env {
          name = "NETSUITE_REVENUE_TBA_TOKEN_SECRET"
          value_source {
            secret_key_ref {
              secret  = google_secret_manager_secret.netsuite_revenue_api["token_secret"].secret_id
              version = "latest"
            }
          }
        }
        env {
          name = "NEXUSCRM_REVENUE_CLIENT_ID"
          value_source {
            secret_key_ref {
              secret  = google_secret_manager_secret.netsuite_revenue_api["client_id"].secret_id
              version = "latest"
            }
          }
        }
        env {
          name = "NEXUSCRM_REVENUE_CLIENT_SECRET"
          value_source {
            secret_key_ref {
              secret  = google_secret_manager_secret.netsuite_revenue_api["client_secret"].secret_id
              version = "latest"
            }
          }
        }
      }
    }
  }

  depends_on = [
    google_storage_bucket_iam_member.netsuite_revenue_runtime_candidate_writer,
    google_secret_manager_secret_iam_member.netsuite_revenue_api_accessor,
  ]
}

resource "google_project_iam_member" "netsuite_revenue_scheduler_run_developer" {
  count = var.enable_netsuite_revenue_to_nexuscrm ? 1 : 0

  project = var.project_id
  role    = "roles/run.developer"
  member  = "serviceAccount:${google_service_account.netsuite_revenue_scheduler[0].email}"
}

resource "google_service_account_iam_member" "netsuite_revenue_scheduler_act_as_runtime" {
  count = var.enable_netsuite_revenue_to_nexuscrm ? 1 : 0

  service_account_id = google_service_account.netsuite_revenue_runtime[0].name
  role               = "roles/iam.serviceAccountUser"
  member             = "serviceAccount:${google_service_account.netsuite_revenue_scheduler[0].email}"
}

resource "google_cloud_scheduler_job" "netsuite_revenue_to_nexuscrm" {
  count = var.enable_netsuite_revenue_to_nexuscrm ? 1 : 0

  project     = var.project_id
  region      = var.region
  name        = "pingcap-netsuite-revenue-to-nexuscrm"
  description = "Disabled by default: freezes a NetSuite candidate only; no CRM API commit arguments are configured"
  schedule    = var.netsuite_revenue_schedule_cron
  time_zone   = var.netsuite_revenue_schedule_timezone
  paused      = var.netsuite_revenue_scheduler_paused

  http_target {
    http_method = "POST"
    uri         = "https://run.googleapis.com/v2/projects/${var.project_id}/locations/${var.region}/jobs/${google_cloud_run_v2_job.netsuite_revenue_to_nexuscrm[0].name}:run"
    oauth_token {
      service_account_email = google_service_account.netsuite_revenue_scheduler[0].email
      scope                 = "https://www.googleapis.com/auth/cloud-platform"
    }
  }

  depends_on = [
    google_cloud_run_v2_job.netsuite_revenue_to_nexuscrm,
    google_project_iam_member.netsuite_revenue_scheduler_run_developer,
    google_service_account_iam_member.netsuite_revenue_scheduler_act_as_runtime,
  ]
}

resource "google_monitoring_alert_policy" "netsuite_revenue_api_failure" {
  count = var.enable_netsuite_revenue_to_nexuscrm ? 1 : 0

  project      = var.project_id
  display_name = "netsuite revenue NexusCRM API job failure"
  combiner     = "OR"
  conditions {
    display_name = "NetSuite revenue API job failed"
    condition_threshold {
      filter = join(" AND ", [
        "resource.type = \"cloud_run_job\"",
        "resource.label.\"job_name\" = \"pingcap-netsuite-revenue-to-nexuscrm\"",
        "metric.type = \"run.googleapis.com/job/completed_execution_count\"",
        "metric.label.\"result\" = \"failed\"",
      ])
      comparison      = "COMPARISON_GT"
      threshold_value = 0
      duration        = "0s"
      trigger {
        count = 1
      }
      aggregations {
        alignment_period   = "600s"
        per_series_aligner = "ALIGN_SUM"
      }
    }
  }
  conditions {
    display_name = "No successful NetSuite revenue candidate freeze in 24 hours"
    condition_absent {
      filter = join(" AND ", [
        "resource.type = \"cloud_run_job\"",
        "resource.label.\"job_name\" = \"pingcap-netsuite-revenue-to-nexuscrm\"",
        "metric.type = \"run.googleapis.com/job/completed_execution_count\"",
        "metric.label.\"result\" = \"succeeded\"",
      ])
      duration = "86400s"
      trigger { count = 1 }
    }
  }
  notification_channels = ["projects/${var.project_id}/notificationChannels/3067816630126861020"]
  alert_strategy { auto_close = "604800s" }
  documentation {
    content   = "The governed NetSuite revenue NexusCRM API Job failed. Inspect only run IDs and candidate/admission/attempt manifest hashes; retry from the same frozen candidate."
    mime_type = "text/markdown"
  }
}
