{{- if and .Values.axon.tokenRefresh.enabled (ne (.Values.axon.provider | default "claude") "vllm") }}
apiVersion: batch/v1
kind: CronJob
metadata:
  name: axon-token-refresh
  labels:
    {{- include "axon.labels" . | nindent 4 }}
    app.kubernetes.io/component: token-refresh
spec:
  schedule: {{ .Values.axon.tokenRefresh.schedule | default "0 */4 * * *" | quote }}
  successfulJobsHistoryLimit: 1
  failedJobsHistoryLimit: 3
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      backoffLimit: 2
      activeDeadlineSeconds: 120
      template:
        spec:
          restartPolicy: Never
          serviceAccountName: axon-token-refresh
          containers:
            - name: refresh
              image: bitnami/kubectl:1.30
              command:
                - /bin/sh
                - -c
                - |
                  set -e

                  # Read current credentials from the K8s secret
                  CREDS=$(kubectl get secret {{ .Values.axon.claudeAuthSecret }} -n {{ .Release.Namespace }} \
                    -o jsonpath='{.data.\.credentials\.json}' | base64 -d)

                  REFRESH_TOKEN=$(echo "$CREDS" | grep -o '"refreshToken":"[^"]*"' | cut -d'"' -f4)
                  if [ -z "$REFRESH_TOKEN" ]; then
                    echo "ERROR: No refreshToken found in credentials"
                    exit 1
                  fi

                  # Call Anthropic OAuth token refresh endpoint
                  RESPONSE=$(curl -sf -X POST https://console.anthropic.com/v1/oauth/token \
                    -H "Content-Type: application/json" \
                    -d "{
                      \"grant_type\": \"refresh_token\",
                      \"refresh_token\": \"$REFRESH_TOKEN\",
                      \"client_id\": \"9d1c250a-e61b-44d9-88ed-5944d1962f5e\"
                    }")

                  # Extract new access token and expiry
                  NEW_ACCESS=$(echo "$RESPONSE" | grep -o '"access_token":"[^"]*"' | cut -d'"' -f4)
                  EXPIRES_IN=$(echo "$RESPONSE" | grep -o '"expires_in":[0-9]*' | cut -d':' -f2)

                  if [ -z "$NEW_ACCESS" ]; then
                    echo "ERROR: Failed to refresh token. Response: $RESPONSE"
                    exit 1
                  fi

                  # Calculate expiresAt in milliseconds
                  NOW_MS=$(date +%s)000
                  EXPIRES_AT=$(( $(date +%s) * 1000 + EXPIRES_IN * 1000 ))

                  # Check if we got a new refresh token (some OAuth providers rotate them)
                  NEW_REFRESH=$(echo "$RESPONSE" | grep -o '"refresh_token":"[^"]*"' | cut -d'"' -f4)
                  if [ -z "$NEW_REFRESH" ]; then
                    NEW_REFRESH="$REFRESH_TOKEN"
                  fi

                  # Preserve existing fields (scopes, subscriptionType, rateLimitTier)
                  SCOPES=$(echo "$CREDS" | grep -o '"scopes":\[[^]]*\]')
                  SUB_TYPE=$(echo "$CREDS" | grep -o '"subscriptionType":"[^"]*"' | cut -d'"' -f4)
                  RATE_TIER=$(echo "$CREDS" | grep -o '"rateLimitTier":"[^"]*"' | cut -d'"' -f4)

                  # Build new credentials JSON
                  NEW_CREDS=$(cat <<ENDCREDS
                  {"claudeAiOauth":{"accessToken":"${NEW_ACCESS}","refreshToken":"${NEW_REFRESH}","expiresAt":${EXPIRES_AT},${SCOPES},"subscriptionType":"${SUB_TYPE}","rateLimitTier":"${RATE_TIER}"}}
                  ENDCREDS
                  )

                  # Update the K8s secret
                  kubectl create secret generic {{ .Values.axon.claudeAuthSecret }} \
                    -n {{ .Release.Namespace }} \
                    --from-literal=.credentials.json="$NEW_CREDS" \
                    --dry-run=client -o yaml | kubectl apply -f -

                  echo "Token refreshed. New expiry: $(date -d @$((EXPIRES_AT / 1000)) -u '+%Y-%m-%d %H:%M:%S UTC')"

                  # Restart Axon pod to pick up new credentials
                  kubectl rollout restart deployment/axon -n {{ .Release.Namespace }}
                  echo "Axon pod restarting with new credentials"
              resources:
                requests:
                  cpu: 50m
                  memory: 64Mi
                limits:
                  cpu: 100m
                  memory: 128Mi
              securityContext:
                allowPrivilegeEscalation: false
                runAsNonRoot: true
                runAsUser: 1001
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: axon-token-refresh
  labels:
    {{- include "axon.labels" . | nindent 4 }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: axon-token-refresh
  labels:
    {{- include "axon.labels" . | nindent 4 }}
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    resourceNames: [{{ .Values.axon.claudeAuthSecret | quote }}]
    verbs: ["get", "update", "patch"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["create"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    resourceNames: ["axon"]
    verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: axon-token-refresh
  labels:
    {{- include "axon.labels" . | nindent 4 }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: axon-token-refresh
subjects:
  - kind: ServiceAccount
    name: axon-token-refresh
    namespace: {{ .Release.Namespace }}
{{- end }}
