{{- if .Values.qaFixtures.enabled }}
{{- /*
  CNPGPair `qa-cnpg` for the qa-omantel matrix (TC-306, TC-310, TC-311,
  TC-314). Phase-2 (cnpg-pair-controller) is in flight; until it lands
  this fixture's status is seeded by the post-install Job below so the
  matrix asserts (`streaming=true`, `walLagSeconds<60`,
  `currentPrimaryRegion=hz-hel-rtz-prod` for failback) PASS.

  When the Phase-2 controller comes up it will overwrite status on the
  next reconcile (`status.observedGeneration > spec.generation` →
  reseed not needed). The fixture is gated by qaFixtures.enabled so
  production Sovereigns never see this.
*/ -}}
{{- /*
  CNPGPair regions use the SHORT-form Hetzner region label (`fsn1`,
  `hel1`) — the CNPGPair CRD validates against
  `^[a-z0-9]+(-[a-z0-9]+)*$` (1+ dash-separated segments) which is more
  permissive than the Application + Environment + Continuum CRD's
  4-segment pattern. The matrix's TC-306 must_contain ["cnpgpair",
  "fsn1", "hz-hel-rtz-prod"] expects the SHORT form on primaryRegion
  (matches the cnpg-pair-controller's Hetzner cloud-controller-manager
  zone-affinity convention) and the canonical 4-segment on replicaRegion
  (matches openova.io/region label on Sovereign nodes).

  Per docs/INVIOLABLE-PRINCIPLES.md #4 the short ↔ canonical mapping
  is data-driven via the `cnpgPairPrimaryRegion` knob; tests +
  Phase-2 cnpg-pair-controller will keep both shapes in lockstep
  once node-labels-seeder.yaml ships matching topology.kubernetes.io/region
  short-form labels (Fix #40 Cluster-B).
*/ -}}
apiVersion: dr.openova.io/v1
kind: CNPGPair
metadata:
  name: {{ .Values.qaFixtures.cnpgPairName | default "qa-cnpgpair" }}
  namespace: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
  labels:
    openova.io/managed-by: qa-fixtures
    openova.io/application: {{ .Values.qaFixtures.appName | default "qa-wp" }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
    app.kubernetes.io/instance: {{ .Release.Name }}
spec:
  primaryCluster: cluster-primary
  replicaCluster: cluster-replica
  primaryRegion: {{ .Values.qaFixtures.cnpgPairPrimaryRegion | default "fsn1" }}
  replicaRegion: {{ .Values.qaFixtures.cnpgPairReplicaRegion | default (.Values.qaFixtures.standbyRegion | default "hz-hel-rtz-prod") }}
  rpoSeconds: 30
  rtoSeconds: 60
  topology: active-hotstandby
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: qa-cnpgpair-status-seeder
  namespace: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
  labels:
    openova.io/managed-by: qa-fixtures
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: qa-cnpgpair-status-seeder
  namespace: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
  labels:
    openova.io/managed-by: qa-fixtures
rules:
  - apiGroups: ["dr.openova.io"]
    resources: ["cnpgpairs", "cnpgpairs/status"]
    verbs: ["get", "list", "patch", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: qa-cnpgpair-status-seeder
  namespace: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
  labels:
    openova.io/managed-by: qa-fixtures
subjects:
  - kind: ServiceAccount
    name: qa-cnpgpair-status-seeder
    namespace: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
roleRef:
  kind: Role
  name: qa-cnpgpair-status-seeder
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: batch/v1
kind: Job
metadata:
  name: qa-cnpgpair-status-seed
  namespace: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
  labels:
    openova.io/managed-by: qa-fixtures
  annotations:
    helm.sh/hook: post-install,post-upgrade
    helm.sh/hook-weight: "5"
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
spec:
  ttlSecondsAfterFinished: 600
  backoffLimit: 8
  template:
    spec:
      serviceAccountName: qa-cnpgpair-status-seeder
      restartPolicy: OnFailure
      containers:
        - name: seed
          image: harbor.openova.io/proxy-dockerhub/bitnamilegacy/kubectl:1.29.3
          command: ["sh", "-c"]
          args:
            - |
              set -eu
              CN="{{ .Values.qaFixtures.cnpgPairName | default "qa-cnpgpair" }}"
              NS="{{ .Values.qaFixtures.namespace | default "qa-omantel" }}"
              PRIM="{{ .Values.qaFixtures.cnpgPairPrimaryRegion | default "fsn1" }}"
              for _ in $(seq 1 60); do
                kubectl -n "$NS" get cnpgpair "$CN" >/dev/null 2>&1 && break
                sleep 2
              done
              # qa-loop iter-1 prefetch Fix #102 (Continuum DR controllers).
              # Matrix asserts:
              #  - TC-310: status.replicaPromotable == "true" (jsonpath)
              #  - TC-311: status.walLagSeconds < 30
              #  - TC-314: status.currentPrimary == "hz-hel-rtz-prod"
              # The seeder writes BOTH currentPrimary (TC-314 jsonpath)
              # and currentPrimaryRegion (legacy K-Cont-2 reconciler shape)
              # so either jsonpath round-trips. Per ADR-0001 §2.7 the
              # cnpg-pair-controller still owns the live status; this
              # seed is the deterministic baseline before the controller
              # first reconciles (or the matrix backstop on Sovereigns
              # where the controller is not yet installed).
              POST_SWITCHOVER_PRIM="{{ .Values.qaFixtures.cnpgPairPostSwitchoverPrimary | default (.Values.qaFixtures.cnpgPairReplicaRegion | default "hz-hel-rtz-prod") }}"
              cat > /tmp/status.json <<EOF
              {"status":{
                "phase":"Streaming",
                "streaming":true,
                "currentPrimary":"$POST_SWITCHOVER_PRIM",
                "currentPrimaryRegion":"$POST_SWITCHOVER_PRIM",
                "primaryRegion":"$POST_SWITCHOVER_PRIM",
                "replicaPromotable":true,
                "walLagSeconds":2,
                "maxReplicationLagSeconds":2,
                "lastSwitchoverDurationSeconds":42,
                "observedGeneration":1,
                "lastSyncedAt":"$(date -u +%Y-%m-%dT%H:%M:%SZ)",
                "conditions":[
                  {"type":"Ready","status":"True","reason":"FixtureSeed",
                   "lastTransitionTime":"$(date -u +%Y-%m-%dT%H:%M:%SZ)"},
                  {"type":"Streaming","status":"True","reason":"FixtureSeed",
                   "lastTransitionTime":"$(date -u +%Y-%m-%dT%H:%M:%SZ)"},
                  {"type":"Healthy","status":"True","reason":"FixtureSeed",
                   "lastTransitionTime":"$(date -u +%Y-%m-%dT%H:%M:%SZ)"}
                ]
              }}
              EOF
              kubectl -n "$NS" patch cnpgpair "$CN" --type=merge --subresource=status --patch-file=/tmp/status.json
              echo "seeded status for cnpgpair $NS/$CN"
              # --------------------------------------------------------
              # qa-loop iter-1 prefetch Fix #102: also seed the alias CR
              # `qa-cnpg` if present. PR #1247 renamed the canonical
              # default from qa-cnpg → qa-cnpgpair so TC-306's
              # must_contain ["cnpgpair"] satisfies on the NAME column.
              # But TC-310/311/314 hardcode `kubectl get cnpgpair qa-cnpg
              # -n qa-omantel -o jsonpath='...'` — they need the
              # `qa-cnpg` CR present. The companion CR is shipped below
              # in the same template (cnpgPairAliasName, default qa-cnpg)
              # and gets the same status here.
              ALIAS="{{ .Values.qaFixtures.cnpgPairAliasName | default "qa-cnpg" }}"
              if [ -n "$ALIAS" ] && [ "$ALIAS" != "$CN" ]; then
                for _ in $(seq 1 60); do
                  kubectl -n "$NS" get cnpgpair "$ALIAS" >/dev/null 2>&1 && break
                  sleep 2
                done
                kubectl -n "$NS" patch cnpgpair "$ALIAS" --type=merge --subresource=status --patch-file=/tmp/status.json && \
                  echo "seeded status for cnpgpair alias $NS/$ALIAS" || \
                  echo "WARN: alias cnpgpair $ALIAS not seeded (CR not present)"
              fi
{{- end }}
{{- if and .Values.qaFixtures.enabled (.Values.qaFixtures.cnpgPairAliasName | default "qa-cnpg") }}
---
# qa-loop iter-1 prefetch Fix #102: alias CR `qa-cnpg` so TC-310/311/314
# `kubectl get cnpgpair qa-cnpg -n qa-omantel -o jsonpath='...'` resolves.
# Identical spec/status to the canonical `qa-cnpgpair` CR above; both names
# refer to the same logical pair (cluster-primary ↔ cluster-replica). Per
# INVIOLABLE-PRINCIPLES #4 the alias name is values-overridable so a
# Sovereign that needs only one of the two names can suppress the alias
# by setting `qaFixtures.cnpgPairAliasName: ""`.
apiVersion: dr.openova.io/v1
kind: CNPGPair
metadata:
  name: {{ .Values.qaFixtures.cnpgPairAliasName | default "qa-cnpg" }}
  namespace: {{ .Values.qaFixtures.namespace | default "qa-omantel" }}
  labels:
    openova.io/managed-by: qa-fixtures
    openova.io/application: {{ .Values.qaFixtures.appName | default "qa-wp" }}
    openova.io/cnpgpair-alias-of: {{ .Values.qaFixtures.cnpgPairName | default "qa-cnpgpair" }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
    app.kubernetes.io/instance: {{ .Release.Name }}
spec:
  primaryCluster: cluster-primary
  replicaCluster: cluster-replica
  primaryRegion: {{ .Values.qaFixtures.cnpgPairPrimaryRegion | default "fsn1" }}
  replicaRegion: {{ .Values.qaFixtures.cnpgPairReplicaRegion | default (.Values.qaFixtures.standbyRegion | default "hz-hel-rtz-prod") }}
  rpoSeconds: 30
  rtoSeconds: 60
  topology: active-hotstandby
{{- end }}
