{{- /*
Catalyst-curated secrets bundle for the SME microservice mesh
(issue #859).

Why this template exists:
  SME services (auth, billing, catalog, console, domain, gateway,
  marketplace, notification, provisioning, tenant) read JWT signing
  keys, OAuth client credentials, SMTP settings, and admin bootstrap
  credentials from a single Kubernetes Secret named `sme-secrets` in
  the `sme` namespace. On contabo-mkt this Secret is hand-rolled in
  clusters/contabo-mkt/apps/sme/data/secrets.yaml. On a freshly
  franchised Sovereign nothing equivalent exists, so 10 of the 11 SME
  pods land in CreateContainerConfigError.

  This template materialises the Secret as part of the chart so any
  Sovereign that flips MARKETPLACE_ENABLED=true gets a working SME
  back-end out of the box.

Key contract (all 11 keys consumed across SME service Deployments):
  - JWT_SECRET             — auto-generated, persistent across reconciles
  - JWT_REFRESH_SECRET     — auto-generated, persistent across reconciles
  - GOOGLE_CLIENT_ID       — operator-supplied via .Values.marketplace.signupPolicy.googleOAuth.clientId
  - GOOGLE_CLIENT_SECRET   — operator-supplied via .Values.marketplace.signupPolicy.googleOAuth.clientSecretRef (lookup'd from a separate Secret); empty placeholder otherwise
  - SMTP_HOST              — .Values.smeSecrets.smtp.host
  - SMTP_PORT              — .Values.smeSecrets.smtp.port (string-quoted)
  - SMTP_FROM              — .Values.smeSecrets.smtp.from
  - SMTP_USER              — .Values.smeSecrets.smtp.user
  - SMTP_PASS              — operator-supplied via .Values.smeSecrets.smtp.passwordSecretRef (lookup'd); empty placeholder otherwise
  - ADMIN_EMAIL            — .Values.smeSecrets.admin.email
  - ADMIN_PASSWORD         — auto-generated, persistent across reconciles

Persistence across reconciles (load-bearing):
  Per the gitea-admin-secret pattern (platform/gitea/chart/templates/
  admin-secret.yaml — see issue #830 Bug 2 + feedback_passwords.md),
  randomly-generated secrets MUST survive helm upgrade / flux re-
  reconciliation. Without `lookup` every reconcile would emit a NEW
  JWT_SECRET, instantly invalidating every active session and
  every refresh token across all 10 services. Same hazard for
  ADMIN_PASSWORD — would lock out every admin on every reconcile.

  Steady state: lookup finds the existing Secret, decodes the
  existing values, and re-encodes them verbatim.
  First install (or `helm template`): lookup returns nil, randAlphaNum
  generates fresh 64-char (alphanum-only) values.
  helm.sh/resource-policy: keep so `helm uninstall` doesn't drop the
  bytes — a re-install picks up the same values via lookup.

Per docs/INVIOLABLE-PRINCIPLES.md #10: NO plaintext credentials in this
template. The randoms are generated by sprig's randAlphaNum and live
only in the Secret bytes. Never echo them.

Per #4 (never hardcode): every static value is overridable via
.Values.smeSecrets.* / .Values.marketplace.signupPolicy.googleOAuth.*
with placeholder defaults (operator brings real values via the
per-Sovereign overlay or admin-console signup form).
*/}}
{{- if and .Values.ingress .Values.ingress.marketplace .Values.ingress.marketplace.enabled -}}
{{- $secretName := .Values.smeSecrets.secretName | default "sme-secrets" -}}
{{- $namespace := .Values.smeSecrets.namespace | default "sme" -}}
{{- /* ---- Persistent randoms via lookup ---- */ -}}
{{- $existing := lookup "v1" "Secret" $namespace $secretName -}}
{{- $jwtSecret := "" -}}
{{- $jwtRefreshSecret := "" -}}
{{- $adminPassword := "" -}}
{{- if and $existing $existing.data $existing.data.JWT_SECRET -}}
  {{- $jwtSecret = $existing.data.JWT_SECRET | b64dec -}}
{{- else -}}
  {{- $jwtSecret = randAlphaNum 64 -}}
{{- end -}}
{{- if and $existing $existing.data $existing.data.JWT_REFRESH_SECRET -}}
  {{- $jwtRefreshSecret = $existing.data.JWT_REFRESH_SECRET | b64dec -}}
{{- else -}}
  {{- $jwtRefreshSecret = randAlphaNum 64 -}}
{{- end -}}
{{- if and $existing $existing.data $existing.data.ADMIN_PASSWORD -}}
  {{- $adminPassword = $existing.data.ADMIN_PASSWORD | b64dec -}}
{{- else -}}
  {{- $adminPassword = randAlphaNum 32 -}}
{{- end -}}
{{- /* ---- Operator-supplied OAuth client secret via separate Secret ---- */ -}}
{{- $googleClientID := "" -}}
{{- $googleClientSecret := "" -}}
{{- with .Values.marketplace.signupPolicy.googleOAuth -}}
  {{- $googleClientID = .clientId | default "" -}}
  {{- if and .clientSecretRef .clientSecretRef.name -}}
    {{- $oauthSecret := lookup "v1" "Secret" $namespace .clientSecretRef.name -}}
    {{- if and $oauthSecret $oauthSecret.data -}}
      {{- $key := .clientSecretRef.key | default "client-secret" -}}
      {{- if index $oauthSecret.data $key -}}
        {{- $googleClientSecret = index $oauthSecret.data $key | b64dec -}}
      {{- end -}}
    {{- end -}}
  {{- end -}}
{{- end -}}
{{- /* ---- Operator-supplied SMTP password via separate Secret ---- */ -}}
{{- $smtpPass := "" -}}
{{- with .Values.smeSecrets.smtp.passwordSecretRef -}}
  {{- if .name -}}
    {{- $smtpSecret := lookup "v1" "Secret" $namespace .name -}}
    {{- if and $smtpSecret $smtpSecret.data -}}
      {{- $key := .key | default "password" -}}
      {{- if index $smtpSecret.data $key -}}
        {{- $smtpPass = index $smtpSecret.data $key | b64dec -}}
      {{- end -}}
    {{- end -}}
  {{- end -}}
{{- end -}}
{{- /*
---- Sovereign SMTP source-wins lookup (issue #934) ------------------

Pre-#934 the auth + notification SME services pinned SMTP_HOST/PORT/
USER/PASS to the bytes the operator placed in this `sme-secrets`
Secret via .Values.smeSecrets.smtp.*. On a freshly franchised
Sovereign nothing populates those values (the per-Sovereign overlay
can't carry plaintext SMTP creds), so auth.yaml's POST /auth/send-pin
returned `failed to send email` and blocked alice signup gate 2 (PIN
delivery).

Fix: the SAME `catalyst-system/sovereign-smtp-credentials` Secret that
catalyst-openova-kc-credentials reads (per A5's pattern in chart
1.4.20) becomes the source-of-truth for the SME services' SMTP env.
Cloud-init seeds that Secret at provision time (issue #883) with the
mothership relay creds OR — once bp-stalwart-sovereign reaches Ready
(slot 95) — with the Sovereign-local relay coordinates. Either way
SME services consume real bytes on first reconcile.

Source-wins precedence: when the source Secret carries non-empty
bytes they override anything in .Values.smeSecrets.smtp.*. The
chart-level defaults remain available as fallbacks for environments
without the A5 seed (legacy contabo path) where the operator brings
the values via overlay. Five fields are read with the canonical key
shape (smtp-host / smtp-port / smtp-from / smtp-user / smtp-pass)
AND the legacy shape (host / port / from / user / password) for
back-compat with the chart 1.4.20 catalyst-openova-kc-credentials
seam.

Source-Secret namespace + name are operator-overridable via
.Values.smeSecrets.smtp.sovereign{Namespace,SecretName} for unusual
topologies (e.g. a per-Sovereign overlay that places the seeded
Secret in a different namespace). Defaults match A5 PR #905.
*/ -}}
{{- $sovSMTPNs := .Values.smeSecrets.smtp.sovereignNamespace | default "catalyst-system" -}}
{{- $sovSMTPName := .Values.smeSecrets.smtp.sovereignSecretName | default "sovereign-smtp-credentials" -}}
{{- $sovSMTPSecret := lookup "v1" "Secret" $sovSMTPNs $sovSMTPName -}}
{{- $sovSMTPHost := "" -}}
{{- $sovSMTPPort := "" -}}
{{- $sovSMTPFrom := "" -}}
{{- $sovSMTPUser := "" -}}
{{- $sovSMTPPass := "" -}}
{{- if and $sovSMTPSecret $sovSMTPSecret.data -}}
  {{- $d := $sovSMTPSecret.data -}}
  {{- /* canonical key shape */ -}}
  {{- if hasKey $d "smtp-host" -}}{{ $sovSMTPHost = index $d "smtp-host" | b64dec -}}{{- end -}}
  {{- if hasKey $d "smtp-port" -}}{{ $sovSMTPPort = index $d "smtp-port" | b64dec -}}{{- end -}}
  {{- if hasKey $d "smtp-from" -}}{{ $sovSMTPFrom = index $d "smtp-from" | b64dec -}}{{- end -}}
  {{- if hasKey $d "smtp-user" -}}{{ $sovSMTPUser = index $d "smtp-user" | b64dec -}}{{- end -}}
  {{- if hasKey $d "smtp-pass" -}}{{ $sovSMTPPass = index $d "smtp-pass" | b64dec -}}{{- end -}}
  {{- /* legacy key shape (back-compat) */ -}}
  {{- if and (eq $sovSMTPHost "") (hasKey $d "host") -}}{{ $sovSMTPHost = index $d "host" | b64dec -}}{{- end -}}
  {{- if and (eq $sovSMTPPort "") (hasKey $d "port") -}}{{ $sovSMTPPort = index $d "port" | b64dec -}}{{- end -}}
  {{- if and (eq $sovSMTPFrom "") (hasKey $d "from") -}}{{ $sovSMTPFrom = index $d "from" | b64dec -}}{{- end -}}
  {{- if and (eq $sovSMTPUser "") (hasKey $d "user") -}}{{ $sovSMTPUser = index $d "user" | b64dec -}}{{- end -}}
  {{- if and (eq $sovSMTPPass "") (hasKey $d "password") -}}{{ $sovSMTPPass = index $d "password" | b64dec -}}{{- end -}}
{{- end -}}
{{- /* Effective values: source-wins for every non-empty source byte */ -}}
{{- $effSMTPHost := ternary $sovSMTPHost (default "" .Values.smeSecrets.smtp.host) (ne $sovSMTPHost "") -}}
{{- $effSMTPPort := ternary $sovSMTPPort (.Values.smeSecrets.smtp.port | toString) (ne $sovSMTPPort "") -}}
{{- $effSMTPFrom := ternary $sovSMTPFrom (default "" .Values.smeSecrets.smtp.from) (ne $sovSMTPFrom "") -}}
{{- $effSMTPUser := ternary $sovSMTPUser (default "" .Values.smeSecrets.smtp.user) (ne $sovSMTPUser "") -}}
{{- $effSMTPPass := ternary $sovSMTPPass $smtpPass (ne $sovSMTPPass "") -}}
apiVersion: v1
kind: Secret
metadata:
  name: {{ $secretName }}
  namespace: {{ $namespace }}
  labels:
    catalyst.openova.io/blueprint: bp-catalyst-platform
    catalyst.openova.io/component: sme-secrets
    app.kubernetes.io/part-of: sme
  annotations:
    # Survive helm uninstall — the Secret outlives the release. A
    # subsequent helm install picks the bytes back up via lookup, so
    # JWT_SECRET / JWT_REFRESH_SECRET / ADMIN_PASSWORD remain stable
    # across reinstall.
    helm.sh/resource-policy: keep
type: Opaque
data:
  # ---- JWT signing keys (auto-generated, persistent) ----
  JWT_SECRET: {{ $jwtSecret | b64enc | quote }}
  JWT_REFRESH_SECRET: {{ $jwtRefreshSecret | b64enc | quote }}
  # ---- Google OAuth (operator-supplied) ----
  GOOGLE_CLIENT_ID: {{ $googleClientID | b64enc | quote }}
  GOOGLE_CLIENT_SECRET: {{ $googleClientSecret | b64enc | quote }}
  # ---- SMTP (issue #934 source-wins from sovereign-smtp-credentials) ----
  # Source-wins precedence: catalyst-system/sovereign-smtp-credentials
  # (seeded by A5's provisioner #883/#905) overrides chart-level
  # defaults whenever it carries non-empty bytes for each field.
  # Empty source ⇒ falls back to .Values.smeSecrets.smtp.* defaults.
  SMTP_HOST: {{ $effSMTPHost | b64enc | quote }}
  SMTP_PORT: {{ $effSMTPPort | b64enc | quote }}
  SMTP_FROM: {{ $effSMTPFrom | b64enc | quote }}
  SMTP_USER: {{ $effSMTPUser | b64enc | quote }}
  SMTP_PASS: {{ $effSMTPPass | b64enc | quote }}
  # ---- Admin bootstrap (email static, password persistent random) ----
  ADMIN_EMAIL: {{ .Values.smeSecrets.admin.email | default "admin@openova.io" | b64enc | quote }}
  ADMIN_PASSWORD: {{ $adminPassword | b64enc | quote }}
{{- end }}
