# Ground warehouse segment (T3, docs/03 + docs/06) — the stationary,
# long-lifecycle half of the system and therefore the most natural Terraform
# territory. Runs in the same k3d cluster as the fleet, in its own namespace
# and with its own state.

locals {
  labels = { "app.kubernetes.io/part-of" = "swarm-ground" }
}

resource "kubernetes_namespace" "ground" {
  metadata {
    name   = var.namespace
    labels = local.labels
  }
}

# --- MinIO object store -------------------------------------------------------

resource "kubernetes_secret" "minio" {
  metadata {
    name      = "minio-credentials"
    namespace = kubernetes_namespace.ground.metadata[0].name
  }
  data = {
    MINIO_ROOT_USER     = var.minio_root_user
    MINIO_ROOT_PASSWORD = var.minio_root_password
  }
}

resource "kubernetes_persistent_volume_claim" "minio" {
  metadata {
    name      = "minio-data"
    namespace = kubernetes_namespace.ground.metadata[0].name
  }
  spec {
    access_modes = ["ReadWriteOnce"]
    resources {
      requests = { storage = var.minio_storage }
    }
  }
}

resource "kubernetes_deployment" "minio" {
  metadata {
    name      = "minio"
    namespace = kubernetes_namespace.ground.metadata[0].name
    labels    = local.labels
  }

  spec {
    replicas = 1
    strategy {
      type = "Recreate" # RWO volume
    }
    selector {
      match_labels = { app = "minio" }
    }
    template {
      metadata {
        labels = merge(local.labels, { app = "minio" })
      }
      spec {
        container {
          name  = "minio"
          image = "minio/minio:RELEASE.2024-06-13T22-53-53Z"
          args  = ["server", "/data", "--console-address", ":9001"]

          env_from {
            secret_ref {
              name = kubernetes_secret.minio.metadata[0].name
            }
          }
          # Air-gap hygiene: no update checks
          env {
            name  = "MINIO_UPDATE"
            value = "off"
          }

          port {
            container_port = 9000
          }
          port {
            container_port = 9001
          }

          volume_mount {
            name       = "store"
            mount_path = "/data"
          }
        }
        volume {
          name = "store"
          persistent_volume_claim {
            claim_name = kubernetes_persistent_volume_claim.minio.metadata[0].name
          }
        }
      }
    }
  }
}

resource "kubernetes_service" "minio" {
  metadata {
    name      = "minio"
    namespace = kubernetes_namespace.ground.metadata[0].name
  }
  spec {
    type     = "NodePort"
    selector = { app = "minio" }
    port {
      name        = "api"
      port        = 9000
      target_port = 9000
    }
    port {
      name        = "console"
      port        = 9001
      target_port = 9001
      node_port   = var.node_ports.minio_console
    }
  }
}

# --- Post-flight offload: T1 lake -> T3 warehouse ------------------------------
# In production this runs on the docking station after a drone lands: only
# sealed partitions move, checksums are verified, then the on-board lake is
# pruned. The simulation compresses that into a periodic rsync-style copy
# plus an object-store mirror.

resource "kubernetes_cron_job_v1" "offload" {
  metadata {
    name      = "offload"
    namespace = kubernetes_namespace.ground.metadata[0].name
    labels    = local.labels
  }

  spec {
    schedule                      = var.offload_schedule
    concurrency_policy            = "Forbid"
    successful_jobs_history_limit = 3
    failed_jobs_history_limit     = 3

    job_template {
      metadata {
        labels = local.labels
      }
      spec {
        backoff_limit = 1
        template {
          metadata {
            labels = local.labels
          }
          spec {
            restart_policy = "Never"

            # Step 1: copy Hive partitions verbatim (T1 layout == T3 layout)
            init_container {
              name    = "copy"
              image   = "busybox:1.36"
              command = ["sh", "-c", "cp -ru /lake/flight_id=* /warehouse/ 2>/dev/null; ls /warehouse | wc -l"]
              volume_mount {
                name       = "lake"
                mount_path = "/lake"
                read_only  = true
              }
              volume_mount {
                name       = "warehouse"
                mount_path = "/warehouse"
              }
            }

            # Step 2: mirror the warehouse into the object store for
            # downstream consumers (training pipelines, replay tooling)
            container {
              name    = "mirror"
              image   = "minio/mc:RELEASE.2024-06-12T14-34-03Z"
              command = ["sh", "-c", "mc alias set store http://minio:9000 \"$MINIO_ROOT_USER\" \"$MINIO_ROOT_PASSWORD\" && mc mb -p store/warehouse && mc mirror --overwrite /warehouse store/warehouse"]
              env_from {
                secret_ref {
                  name = kubernetes_secret.minio.metadata[0].name
                }
              }
              volume_mount {
                name       = "warehouse"
                mount_path = "/warehouse"
                read_only  = true
              }
            }

            volume {
              name = "lake"
              host_path {
                path = var.lake_host_path
              }
            }
            volume {
              name = "warehouse"
              host_path {
                path = var.warehouse_host_path
                type = "DirectoryOrCreate"
              }
            }
          }
        }
      }
    }
  }
}

# --- Warehouse explorer: historical read-only SQL over all flights -------------

resource "kubernetes_deployment" "warehouse_explorer" {
  metadata {
    name      = "warehouse-explorer"
    namespace = kubernetes_namespace.ground.metadata[0].name
    labels    = local.labels
  }

  spec {
    replicas = 1
    selector {
      match_labels = { app = "warehouse-explorer" }
    }
    template {
      metadata {
        labels = merge(local.labels, { app = "warehouse-explorer" })
      }
      spec {
        container {
          name              = "explorer"
          image             = var.simulator_image
          image_pull_policy = "Never"
          command           = ["python", "explorer/server.py"]
          env {
            name  = "DATA_DIR"
            value = "/warehouse"
          }
          port {
            container_port = 8088
          }
          volume_mount {
            name       = "warehouse"
            mount_path = "/warehouse"
            read_only  = true
          }
        }
        volume {
          name = "warehouse"
          host_path {
            path = var.warehouse_host_path
            type = "DirectoryOrCreate"
          }
        }
      }
    }
  }
}

resource "kubernetes_service" "warehouse_explorer" {
  metadata {
    name      = "warehouse-explorer"
    namespace = kubernetes_namespace.ground.metadata[0].name
  }
  spec {
    type     = "NodePort"
    selector = { app = "warehouse-explorer" }
    port {
      port        = 8088
      target_port = 8088
      node_port   = var.node_ports.warehouse_explorer
    }
  }
}
