{{- $advertisedListenersOverride := first (pluck "advertised.listeners" .Values.configurationOverrides) }}
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: {{ include "kafka.fullname" . }}
  labels:
    app: {{ include "kafka.name" . }}
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
spec:
  serviceName: {{ include "kafka.fullname" . }}-headless
  podManagementPolicy: {{ .Values.podManagementPolicy }}
  updateStrategy:
{{ toYaml .Values.updateStrategy | indent 4 }}
  replicas: {{ default 3 .Values.replicas }}
  template:
    metadata:
{{- if and .Values.prometheus.jmx.enabled  (not .Values.prometheus.operator.enabled) }}
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: {{ .Values.prometheus.jmx.port | quote }}
{{- end }}
      labels:
        app: {{ include "kafka.name" . }}
        release: {{ .Release.Name }}
    spec:
{{- if .Values.schedulerName }}
      schedulerName: "{{ .Values.schedulerName }}"
{{- end }}
{{- if .Values.rbac.enabled }}
      serviceAccountName: {{ .Release.Name }}
{{- end }}
    {{- if .Values.external.enabled }}
      ## ref: https://github.com/Yolean/kubernetes-kafka/blob/master/kafka/50kafka.yml
      initContainers:
      - name: init-ext
        image: "{{ .Values.external.init.image }}:{{ .Values.external.init.imageTag }}"
        imagePullPolicy: "{{ .Values.external.init.imagePullPolicy }}"
        command:
          - sh
          - -euxc
          - "kubectl label pods ${POD_NAME} --namespace ${POD_NAMESPACE} pod=${POD_NAME}"
        env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
    {{- end }}
{{- if .Values.tolerations }}
      tolerations:
{{ toYaml .Values.tolerations | indent 8 }}
{{- end }}
{{- if .Values.affinity }}
      affinity:
{{ toYaml .Values.affinity | indent 8 }}
{{- end }}
{{- if .Values.nodeSelector }}
      nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
{{- end }}
      containers:
      {{- if .Values.prometheus.jmx.enabled }}
      - name: metrics
        image: "{{ .Values.prometheus.jmx.image }}:{{ .Values.prometheus.jmx.imageTag }}"
        command:
        - java
        - -XX:+UnlockExperimentalVMOptions
        - -XX:+UseCGroupMemoryLimitForHeap
        - -XX:MaxRAMFraction=1
        - -XshowSettings:vm
        - -jar
        - jmx_prometheus_httpserver.jar
        - {{ .Values.prometheus.jmx.port | quote }}
        - /etc/jmx-kafka/jmx-kafka-prometheus.yml
        ports:
        - containerPort: {{ .Values.prometheus.jmx.port }}
        resources:
{{ toYaml .Values.prometheus.jmx.resources | indent 10 }}
        volumeMounts:
        - name: jmx-config
          mountPath: /etc/jmx-kafka
      {{- end }}
      - name: {{ include "kafka.name" . }}-broker
        image: "{{ .Values.image }}:{{ .Values.imageTag }}"
        imagePullPolicy: "{{ .Values.imagePullPolicy }}"
        livenessProbe:
          exec:
            command:
              - sh
              - -ec
              - /usr/bin/jps | /bin/grep -q SupportedKafka
          initialDelaySeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          tcpSocket:
            port: kafka
          initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
          periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
          timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
          successThreshold: {{ .Values.readinessProbe.successThreshold }}
          failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
        ports:
        - containerPort: 9092
          name: kafka
        {{- if .Values.external.enabled }}
          {{- $replicas := .Values.replicas | int }}
          {{- $root := . }}
          {{- range $i, $e := until $replicas }}
        - containerPort: {{ add $root.Values.external.firstListenerPort $i }}
          name: external-{{ $i }}
          {{- end }}
        {{- end }}
        {{- if .Values.prometheus.jmx.enabled }}
        - containerPort: {{ .Values.jmx.port }}
          name: jmx
        {{- end }}
        {{- if .Values.additionalPorts }}
{{ toYaml .Values.additionalPorts | indent 8 }}
        {{- end }}
        resources:
{{ toYaml .Values.resources | indent 10 }}
        env:
        {{- if .Values.prometheus.jmx.enabled }}
        - name: JMX_PORT
          value: "{{ .Values.jmx.port }}"
        {{- end }}
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: KAFKA_HEAP_OPTS
          value: {{ .Values.kafkaHeapOptions }}
        {{- if not (hasKey .Values.configurationOverrides "zookeeper.connect") }}
        - name: KAFKA_ZOOKEEPER_CONNECT
          value: {{ include "zookeeper.url" . | quote }}
        {{- end }}
        {{- if not (hasKey .Values.configurationOverrides "log.dirs") }}
        - name: KAFKA_LOG_DIRS
          value: {{ printf "%s/%s" .Values.persistence.mountPath .Values.logSubPath | quote }}
        {{- end }}
        {{- range $key, $value := .Values.configurationOverrides }}
        - name: {{ printf "KAFKA_%s" $key | replace "." "_" | upper | quote }}
          value: {{ $value | quote }}
        {{- end }}
        {{- if .Values.jmx.port }}
        - name: KAFKA_JMX_PORT
          value: "{{ .Values.jmx.port }}"
        {{- end }}
        # This is required because the Downward API does not yet support identification of
        # pod numbering in statefulsets. Thus, we are required to specify a command which
        # allows us to extract the pod ID for usage as the Kafka Broker ID.
        # See: https://github.com/kubernetes/kubernetes/issues/31218
        command:
        - sh
        - -exc
        - |
          export KAFKA_BROKER_ID=${HOSTNAME##*-} && \
          export KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://${POD_IP}:9092{{ if kindIs "string" $advertisedListenersOverride }}{{ printf ",%s" $advertisedListenersOverride }}{{ end }} && \
          exec /etc/confluent/docker/run
        volumeMounts:
        - name: datadir
          mountPath: {{ .Values.persistence.mountPath | quote }}
      volumes:
      {{- if not .Values.persistence.enabled }}
      - name: datadir
        emptyDir: {}
      {{- end }}
      {{- if .Values.prometheus.jmx.enabled }}
      - name: jmx-config
        configMap:
          {{- if .Values.jmx.configMap.overrideName }}
          name: {{ .Values.jmx.configMap.overrideName }}
          {{- else }}
          name: {{ include "kafka.fullname" . }}-metrics
          {{- end }}
      {{- end }}
      terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
  {{- if .Values.persistence.enabled }}
  volumeClaimTemplates:
  - metadata:
      name: datadir
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: {{ .Values.persistence.size }}
      {{- if .Values.persistence.storageClass }}
      {{- if (eq "-" .Values.persistence.storageClass) }}
      storageClassName: ""
      {{- else }}
      storageClassName: "{{ .Values.persistence.storageClass }}"
      {{- end }}
      {{- end }}
  {{- end }}
