{{- /*
Auto-provision the Stalwart admin Secret (issue #898).

Why this template exists:
  templates/deployment.yaml + templates/mailbox-provision-job.yaml
  reference a secretKeyRef on `.Values.admin.secretName` (key
  `ADMIN_PASSWORD`) via the `bp-stalwart-tenant.adminPasswordEnv`
  helper. The 0.1.0 chart relied on EITHER an operator-supplied
  SealedSecret OR an ExternalSecret rendered by
  `admin-externalsecret.yaml` — but the ExternalSecret only renders
  when `admin.externalSecret.remoteRef.key` is non-empty (smoke-render
  concession), which is NEVER true on a fresh per-tenant install
  (#898 evidence on otech103: alice tenant landed in
  CreateContainerConfigError because no `stalwart-admin` Secret existed
  in the tenant namespace).

  This template ALWAYS materialises the Secret with a randomly-
  generated ADMIN_PASSWORD when no externally-managed source is
  active, so a freshly-franchised SME tenant gets a usable mail
  server out of the box without operator hand-rolling. Mirrors the
  established pattern in `products/catalyst/chart/templates/
  marketplace-api/secret.yaml` (jwt-secret), which itself was added
  for the same fresh-Sovereign breakage class (#887).

Render gates (skip auto-provisioning when an authoritative source
is in play):
  1. `admin.autoProvision.enabled=false` — operator opts out (e.g.
     they pre-create a SealedSecret named <secretName> in the tenant
     namespace).
  2. `admin.externalSecret.enabled=true` AND
     `admin.externalSecret.remoteRef.key` non-empty — the
     ExternalSecret in admin-externalsecret.yaml will own the Secret;
     two controllers fighting over the same Secret is a known
     anti-pattern (chart docs already warn).

Persistence across reconciles (load-bearing):
  Per the gitea-admin-secret + sme-secrets pattern (issues #830/#859/
  #887), the randomly-generated ADMIN_PASSWORD MUST survive
  `helm upgrade` / Flux re-reconciliation. Without `lookup`, every
  reconcile would emit a NEW password, immediately invalidating
  Stalwart's running RocksDB-stored credential and locking the SME
  admin out (RocksDB only accepts the bootstrap password on first
  install — subsequent password changes go through the admin API).

  Steady state: lookup finds the existing Secret, decodes the value,
  and re-encodes verbatim.
  First install (or `helm template`): lookup returns nil; `randAlphaNum`
  generates a fresh 32-character value (per global CLAUDE.md credential
  hygiene + INVIOLABLE-PRINCIPLES.md #10 — fully random, no dictionary
  words, no human-memorizable patterns).

  helm.sh/resource-policy: keep — `helm uninstall` doesn't drop the
  bytes; a re-install picks up the same value via lookup.

Per docs/INVIOLABLE-PRINCIPLES.md #10: NO plaintext credentials in
this template. The random value is generated by sprig's randAlphaNum
inside the lookup-or-generate switch and lives ONLY in the resulting
Secret bytes. NEVER echo, print, or persist the generated value
outside the Secret manifest.
*/}}
{{- $a := .Values.admin -}}
{{- $auto := $a.autoProvision | default dict -}}
{{- $autoEnabled := dig "enabled" true $auto -}}
{{- $eso := $a.externalSecret | default dict -}}
{{- $esoRemote := $eso.remoteRef | default dict -}}
{{- $esoActive := and $eso.enabled $esoRemote.key -}}
{{- if and $autoEnabled (not $esoActive) -}}
{{- $secretName := $a.secretName -}}
{{- $namespace := .Release.Namespace -}}
{{- /* ---- Persistent random via lookup ---- */ -}}
{{- $existing := lookup "v1" "Secret" $namespace $secretName -}}
{{- $adminPassword := "" -}}
{{- if and $existing $existing.data (index $existing.data "ADMIN_PASSWORD") -}}
  {{- $adminPassword = index $existing.data "ADMIN_PASSWORD" | b64dec -}}
{{- else -}}
  {{- $adminPassword = randAlphaNum 32 -}}
{{- end -}}
apiVersion: v1
kind: Secret
metadata:
  name: {{ $secretName | quote }}
  namespace: {{ $namespace | quote }}
  labels:
    {{- include "bp-stalwart-tenant.labels" . | nindent 4 }}
    catalyst.openova.io/component: stalwart-admin
  annotations:
    # Survive helm uninstall — the Secret outlives the release. A
    # subsequent helm install picks the bytes back up via lookup, so
    # ADMIN_PASSWORD remains stable across reinstall (mirrors the
    # gitea-admin-secret / marketplace-api-secrets pattern, #830/#887).
    helm.sh/resource-policy: keep
type: Opaque
data:
  ADMIN_PASSWORD: {{ $adminPassword | b64enc | quote }}
{{- end }}
