#!/usr/bin/env bash
#
# Sync the mail.dezky.eu TLS cert from the cluster (issued by cert-manager) to
# Stalwart on the host. The host IS the k3s node, so we read the secret via the
# local kubeconfig — no external machinery. Reloads Stalwart only when the cert
# actually changed (cert-manager renews ~30 days before expiry).
#
# Run by stalwart-cert-sync.timer (every 12h + on boot). Safe to run by hand.
#
# Forward dependency: needs the fleet layer to have created the TLS secret
# (default: namespace 'mail', secret 'mail-tls'). Until then this is a no-op and
# Stalwart keeps using the self-signed bootstrap cert from install.sh.

set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
info()  { echo -e "${BLUE}[INFO]${NC}  $*"; }
ok()    { echo -e "${GREEN}[OK]${NC}    $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC}  $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }

TLS_NAMESPACE="${TLS_NAMESPACE:-mail}"
TLS_SECRET="${TLS_SECRET:-mail-tls}"
TLS_DIR="/opt/stalwart/etc/tls"
KUBECONFIG_PATH="${KUBECONFIG:-/etc/rancher/k3s/k3s.yaml}"

# kubectl: prefer standalone, fall back to the k3s-bundled one
if command -v kubectl >/dev/null 2>&1; then
    KUBECTL=(kubectl)
elif command -v k3s >/dev/null 2>&1; then
    KUBECTL=(k3s kubectl)
else
    error "Neither kubectl nor k3s found — is the node provisioned yet?"
    exit 1
fi
export KUBECONFIG="$KUBECONFIG_PATH"

# Pull the secret (no-op if it doesn't exist yet)
if ! "${KUBECTL[@]}" -n "$TLS_NAMESPACE" get secret "$TLS_SECRET" >/dev/null 2>&1; then
    warn "Secret ${TLS_NAMESPACE}/${TLS_SECRET} not present yet — cert-manager hasn't issued it. Skipping."
    exit 0
fi

TMP_CRT="$(mktemp)"; TMP_KEY="$(mktemp)"
trap 'rm -f "$TMP_CRT" "$TMP_KEY"' EXIT

"${KUBECTL[@]}" -n "$TLS_NAMESPACE" get secret "$TLS_SECRET" \
    -o jsonpath='{.data.tls\.crt}' | base64 -d > "$TMP_CRT"
"${KUBECTL[@]}" -n "$TLS_NAMESPACE" get secret "$TLS_SECRET" \
    -o jsonpath='{.data.tls\.key}' | base64 -d > "$TMP_KEY"

if [[ ! -s "$TMP_CRT" || ! -s "$TMP_KEY" ]]; then
    error "Fetched cert or key is empty — leaving current cert in place."
    exit 1
fi

# Only reload if something changed (compare hashes)
changed=0
mkdir -p "$TLS_DIR"
if ! cmp -s "$TMP_CRT" "$TLS_DIR/cert.pem" 2>/dev/null; then changed=1; fi
if ! cmp -s "$TMP_KEY" "$TLS_DIR/key.pem"  2>/dev/null; then changed=1; fi

if [[ $changed -eq 0 ]]; then
    info "Cert unchanged — nothing to do."
    exit 0
fi

install -o stalwart -g stalwart -m 0644 "$TMP_CRT" "$TLS_DIR/cert.pem"
install -o stalwart -g stalwart -m 0640 "$TMP_KEY" "$TLS_DIR/key.pem"
ok "Updated mail TLS cert from ${TLS_NAMESPACE}/${TLS_SECRET}."

# SIGHUP Stalwart to reload certs without dropping connections
if systemctl is-active --quiet stalwart-mail; then
    systemctl reload stalwart-mail && ok "Reloaded stalwart-mail (SIGHUP)."
else
    warn "stalwart-mail not active — cert staged, will be used on next start."
fi
