#@ load("@ytt:data", "data")

#@ ns = data.values.application.namespace

#! mittwald can't generate UUIDs and ocis-settings rejects non-UUID user-ids
#! with "must be in a valid format". This Job ensures the admin secret's
#! user-id is a valid UUID v4, generating one if missing/invalid. Idempotent:
#! a valid existing UUID is preserved (so production's pre-existing admin
#! user-id is not rotated).

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ocis-admin-user-id-init
  namespace: #@ ns
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/sync-wave: "-2"

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ocis-admin-user-id-init
  namespace: #@ ns
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/sync-wave: "-2"
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "patch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ocis-admin-user-id-init
  namespace: #@ ns
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/sync-wave: "-2"
subjects:
  - kind: ServiceAccount
    name: ocis-admin-user-id-init
    namespace: #@ ns
roleRef:
  kind: Role
  name: ocis-admin-user-id-init
  apiGroup: rbac.authorization.k8s.io

---
apiVersion: batch/v1
kind: Job
metadata:
  name: ocis-admin-user-id-init
  namespace: #@ ns
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/sync-wave: "-1"
    argocd.argoproj.io/sync-options: Replace=true
spec:
  ttlSecondsAfterFinished: 300
  backoffLimit: 10
  template:
    spec:
      serviceAccountName: ocis-admin-user-id-init
      restartPolicy: OnFailure
      securityContext:
        runAsNonRoot: true
        runAsUser: 65532
        runAsGroup: 65532
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: ensure-uuid
          image: alpine/k8s:1.32.3
          command:
            - sh
            - -c
            - |
              set -eu
              UUID_RE='^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'

              for i in $(seq 1 30); do
                if kubectl -n "${NAMESPACE}" get secret ocis-admin-user >/dev/null 2>&1; then break; fi
                echo "[admin-user-id-init] waiting for ocis-admin-user secret..."
                sleep 2
              done

              CUR_B64=$(kubectl -n "${NAMESPACE}" get secret ocis-admin-user -o jsonpath='{.data.user-id}' 2>/dev/null || echo "")
              if [ -n "${CUR_B64}" ]; then
                CUR=$(echo "${CUR_B64}" | base64 -d)
                if echo "${CUR}" | grep -Eq "${UUID_RE}"; then
                  echo "[admin-user-id-init] user-id is a valid UUID, leaving alone"
                  exit 0
                fi
                echo "[admin-user-id-init] user-id present but not a valid UUID; replacing"
              else
                echo "[admin-user-id-init] user-id missing; generating"
              fi

              NEW_UUID=$(cat /proc/sys/kernel/random/uuid)
              NEW_B64=$(printf '%s' "${NEW_UUID}" | base64 -w0)
              kubectl -n "${NAMESPACE}" patch secret ocis-admin-user --type=json \
                -p "[{\"op\":\"replace\",\"path\":\"/data/user-id\",\"value\":\"${NEW_B64}\"}]" \
                || kubectl -n "${NAMESPACE}" patch secret ocis-admin-user --type=json \
                  -p "[{\"op\":\"add\",\"path\":\"/data/user-id\",\"value\":\"${NEW_B64}\"}]"
              echo "[admin-user-id-init] set user-id to ${NEW_UUID}"
          env:
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL
