locals {
  name_prefix   = "${var.session_name}-gcp-regional"
  owner_label   = substr(trim(replace(lower(var.owner), "/[^a-z0-9_-]/", "-"), "-_"), 0, 63)
  machine_type  = "n2-standard-8"
  root_disk_gib = 160
  subnet_cidr   = "10.250.0.0/24"
  o11y_name     = "${local.name_prefix}-o11y"
  o11y_psc_cidr = "10.250.1.0/28"
  o11y_bucket   = "${var.seed_project_id}-${var.session_name}-o11y"
  runtime_image = "projects/ubuntu-os-cloud/global/images/family/ubuntu-2404-lts-amd64"
  labels = {
    cp9-owner   = local.owner_label
    cp9-session = var.session_name
    cp9-managed = "terraform-gcp-runtime"
  }
  cleanup_descriptor = jsonencode({
    cp9-managed = "terraform-gcp-runtime"
    cp9-owner   = var.owner
    cp9-region  = var.region
    cp9-session = var.session_name
    cp9-ttl     = var.ttl_expires_at
    cp9-zone    = var.zone
  })
}

data "google_service_account" "runtime" {
  account_id = var.runtime_service_account_email
  project    = var.seed_project_id
}

resource "google_compute_network" "regional" {
  name                    = local.name_prefix
  project                 = var.seed_project_id
  auto_create_subnetworks = false
  routing_mode            = "REGIONAL"
  description             = local.cleanup_descriptor
}

resource "google_compute_subnetwork" "regional" {
  name                     = local.name_prefix
  project                  = var.seed_project_id
  region                   = var.region
  network                  = google_compute_network.regional.id
  ip_cidr_range            = local.subnet_cidr
  private_ip_google_access = true
  description              = local.cleanup_descriptor
}

resource "google_compute_subnetwork" "o11y_psc_nat" {
  name          = "${local.o11y_name}-psc"
  project       = var.seed_project_id
  region        = var.region
  network       = google_compute_network.regional.id
  ip_cidr_range = local.o11y_psc_cidr
  purpose       = "PRIVATE_SERVICE_CONNECT"
  description   = local.cleanup_descriptor
}

resource "google_compute_address" "regional" {
  name         = local.name_prefix
  project      = var.seed_project_id
  region       = var.region
  address_type = "EXTERNAL"
  description  = local.cleanup_descriptor
}

resource "google_compute_firewall" "iap_ssh" {
  name        = "${local.name_prefix}-iap-ssh"
  project     = var.seed_project_id
  network     = google_compute_network.regional.name
  direction   = "INGRESS"
  description = local.cleanup_descriptor

  source_ranges = ["35.235.240.0/20"]
  target_tags   = [local.name_prefix]

  allow {
    protocol = "tcp"
    ports    = ["22"]
  }
}

resource "google_compute_firewall" "regional_kong" {
  name        = "${local.name_prefix}-kong"
  project     = var.seed_project_id
  network     = google_compute_network.regional.name
  direction   = "INGRESS"
  description = local.cleanup_descriptor

  source_ranges = [var.primary_aws_source_cidr]
  target_tags   = [local.name_prefix]

  allow {
    protocol = "tcp"
    ports    = ["443"]
  }
}

resource "google_compute_firewall" "regional_o11y" {
  name        = local.o11y_name
  project     = var.seed_project_id
  network     = google_compute_network.regional.name
  direction   = "INGRESS"
  description = local.cleanup_descriptor

  source_ranges = [local.o11y_psc_cidr, "35.191.0.0/16", "130.211.0.0/22"]
  target_tags   = [local.name_prefix]

  allow {
    protocol = "tcp"
    ports    = ["80"]
  }
}

resource "google_compute_instance" "regional" {
  name         = local.name_prefix
  project      = var.seed_project_id
  zone         = var.zone
  machine_type = local.machine_type
  description  = local.cleanup_descriptor

  allow_stopping_for_update = true
  deletion_protection       = false
  labels                    = local.labels
  tags                      = [local.name_prefix]

  boot_disk {
    auto_delete = true
    initialize_params {
      image = local.runtime_image
      size  = local.root_disk_gib
      type  = "pd-balanced"
    }
  }

  network_interface {
    subnetwork = google_compute_subnetwork.regional.id
    access_config {
      nat_ip = google_compute_address.regional.address
    }
  }

  metadata = {
    enable-oslogin         = "TRUE"
    block-project-ssh-keys = "TRUE"
    cp9-owner              = var.owner
    cp9-session            = var.session_name
    cp9-ttl                = var.ttl_expires_at
  }

  service_account {
    email  = data.google_service_account.runtime.email
    scopes = ["cloud-platform"]
  }

  shielded_instance_config {
    enable_integrity_monitoring = true
    enable_secure_boot          = true
    enable_vtpm                 = true
  }

  lifecycle {
    precondition {
      condition     = var.runtime_service_account_email == "cp9-developer@${var.seed_project_id}.iam.gserviceaccount.com"
      error_message = "runtime_service_account_email must be the shared cp9-developer identity in seed_project_id."
    }
  }
}

resource "google_compute_instance_group" "o11y" {
  name        = local.o11y_name
  project     = var.seed_project_id
  zone        = var.zone
  description = local.cleanup_descriptor
  instances   = [google_compute_instance.regional.id]
}

resource "google_compute_region_health_check" "o11y" {
  name        = local.o11y_name
  project     = var.seed_project_id
  region      = var.region
  description = local.cleanup_descriptor

  check_interval_sec  = 5
  timeout_sec         = 5
  healthy_threshold   = 1
  unhealthy_threshold = 3

  tcp_health_check {
    port = 80
  }
}

resource "google_compute_region_backend_service" "o11y" {
  name                  = local.o11y_name
  project               = var.seed_project_id
  region                = var.region
  description           = local.cleanup_descriptor
  protocol              = "TCP"
  load_balancing_scheme = "INTERNAL"
  health_checks         = [google_compute_region_health_check.o11y.id]

  backend {
    group          = google_compute_instance_group.o11y.id
    balancing_mode = "CONNECTION"
  }
}

resource "google_compute_forwarding_rule" "o11y" {
  name                  = local.o11y_name
  project               = var.seed_project_id
  region                = var.region
  description           = local.cleanup_descriptor
  load_balancing_scheme = "INTERNAL"
  ip_protocol           = "TCP"
  ports                 = ["80"]
  network               = google_compute_network.regional.id
  subnetwork            = google_compute_subnetwork.regional.id
  backend_service       = google_compute_region_backend_service.o11y.id
  labels                = local.labels
}

resource "google_compute_service_attachment" "o11y" {
  name                  = local.o11y_name
  project               = var.seed_project_id
  region                = var.region
  description           = local.cleanup_descriptor
  connection_preference = "ACCEPT_MANUAL"
  enable_proxy_protocol = false
  nat_subnets           = [google_compute_subnetwork.o11y_psc_nat.id]
  target_service        = google_compute_forwarding_rule.o11y.id

  lifecycle {
    # The O11Y Regional controller owns per-Product consumer admission.
    ignore_changes = [consumer_accept_lists]
  }
}

resource "google_storage_bucket" "o11y" {
  name                        = local.o11y_bucket
  project                     = var.seed_project_id
  location                    = upper(var.region)
  force_destroy               = true
  uniform_bucket_level_access = true
  labels                      = local.labels

  lifecycle {
    precondition {
      condition     = length(local.o11y_bucket) <= 63
      error_message = "the GCP Project and session names are too long for the O11Y bucket contract"
    }
  }
}
