apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "graphscope-store.fullname" . }}
  namespace: {{ .Release.Namespace }}
  labels: {{- include "common.labels.standard" . | nindent 4 }}
    app.kubernetes.io/component: configmap
    {{- if .Values.commonLabels }}
    {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }}
    {{- end }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
data:
  groot.config: |-
    ## Common Config

{{- if .Values.distributed.enabled }}
    rpc.port=55555
    discovery.mode={{ .Values.discoveryMode }}
    role.name=ROLE
    node.idx=INDEX
    release.full.name={{ include "graphscope-store.fullname" . }}
{{- else }}
    rpc.port=0
    discovery.mode=zookeeper
    role.name=""
    node.idx=0
    release.full.name=localhost
{{- end }}

    store.node.count={{ .Values.store.replicaCount }}
    frontend.node.count={{ .Values.frontend.replicaCount }}
    coordinator.node.count={{ .Values.coordinator.replicaCount }}
    partition.count={{ .Values.store.replicaCount | mul 16 }}

    ## Frontend Config
    frontend.service.port={{ .Values.frontend.service.servicePort }}
    frontend.service.httpPort={{ .Values.frontend.service.httpPort }}
    frontend.server.id=INDEX
    frontend.server.num={{ .Values.frontend.replicaCount }}

    ## Store Config
    store.data.path={{ .Values.storeDataPath }}
    store.write.thread.count={{ .Values.storeWriteThreadCount }}
    store.queue.buffer.size={{ .Values.storeQueueBufferSize }}

    ## Zk Config
    zk.base.path={{ .Values.zkBasePath }}
    zk.connect.string={{ printf "%s-headless" (include "graphscope-store.zookeeper.fullname" .) }}

    ## Kafka Config
    kafka.servers={{ include "graphscope-store.kafka.brokerlist" . }}
    kafka.topic={{ .Values.kafkaTopic }}
    kafka.producer.custom.configs={{ .Values.kafkaProducerCustomConfigs }}
    kafka.test.cluster.enable=false

    ## Frontend Config
    gremlin.server.port=12312
    ## disable neo4j when launching groot server by default
    neo4j.bolt.server.disabled=true
  
    ## GOpt config
    graph.planner.is.on={{ .Values.graphPlannerIsOn }}
    graph.planner.opt={{ .Values.graphPlannerOpt }}
    graph.planner.rules={{ .Values.graphPlannerRules }}
    graph.physical.opt={{ .Values.graphPhysicalOpt }}
    gremlin.script.language.name={{ .Values.gremlinScriptLanguageName }}
    query.execution.timeout.ms={{ .Values.queryExecutionTimeoutMs }}
    graph.planner.join.min.pattern.size={{ .Values.graphPlannerJoinMinPatternSize }}
    graph.planner.cbo.glogue.size={{ .Values.graphPlannerCboGlogueSize }}

    log4rs.config=LOG4RS_CONFIG
    ## Auth config
    auth.username={{ .Values.auth.username }}
    auth.password={{ .Values.auth.password }}

    # Pegasus config
    pegasus.hosts=PEGASUS_HOSTS  # this is used by ir server to compute the server size
    pegasus.worker.num={{ .Values.pegasus.worker.num }}
    pegasus.timeout={{ .Values.pegasus.timeout }}
    pegasus.batch.size=1024
    pegasus.output.capacity=16

    gaia.rpc.port=60000
    gaia.engine.port=60001
    gaia.write.timeout.ms=5000

    ## Secondary config
    secondary.instance.enabled={{ .Values.secondary.enabled }}
    store.data.secondary.path={{ .Values.secondary.storeDataPath }}
    store.gc.interval.ms={{ .Values.storeGcIntervalMs }}
    store.catchup.interval.ms={{ .Values.storeCatchupIntervalMs }}

    write.ha.enabled={{ .Values.backup.enabled }}

    ## Coordinator Config
    rpc.max.bytes.mb={{ .Values.rpcMaxBytesMb }}
    snapshot.increase.interval.ms={{ .Values.snapshotIncreaseIntervalMs }}
    offsets.persist.interval.ms={{ .Values.offsetsPersistIntervalMs }}
    file.meta.store.path={{ .Values.fileMetaStorePath }}
    log.recycle.enable={{ .Values.logRecycleEnable }}
    collect.statistics={{ .Values.collect.statistics.enabled }}
    collect.statistics.interval.min={{ .Values.collect.statistics.interval }}
    collect.statistics.initial.delay.min={{ .Values.collect.statistics.initial.delay }}
    log.recycle.offset.reserve={{ .Values.logRecycleOffsetReserve }}

    ## Extra Config
    {{- if .Values.extraConfig }}
    {{- $config_list := regexSplit ";" .Values.extraConfig -1 }}
    {{- range $config_list }}
    {{ . }}
    {{- end }}
    {{- end }}
  setup.sh: |-
    #!/bin/bash

    sudo chown -R graphscope:graphscope {{ .Values.storeDataPath }} || true
    sudo chown -R graphscope:graphscope /etc/groot || true
    sudo chown -R graphscope:graphscope /var/log/graphscope || true

    [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
    ordinal=${BASH_REMATCH[1]}

    pegasus_hosts=""
    i=0
    while [ $i -ne $STORE_COUNT ]; do
      pod=`echo $DNS_NAME_PREFIX_STORE | sed -e "s/{}/$i/g"`
      # 60001 is fixed gaia engine port
      pegasus_hosts="${pegasus_hosts},${pod}:60001"
      i=$(($i+1))
    done
    pegasus_hosts=${pegasus_hosts:1}

    sudo sed  -e "s/ROLE/${ROLE}/g" \
              -e "s/INDEX/${ordinal}/g" \
              -e "s/PEGASUS_HOSTS/${pegasus_hosts}/g" \
              -e "s@LOG4RS_CONFIG@${GRAPHSCOPE_HOME}/groot/conf/log4rs.yml@g" \
    /etc/groot/groot.config.tpl | sudo tee -a /etc/groot/groot.config

    export LOG_NAME=graphscope-store
    export GROOT_CONF_FILE=/etc/groot/groot.config

    export OTEL_SDK_DISABLED={{ not .Values.otel.enabled }}

    {{- if .Values.otel.enabled }}
    export OTEL_TRACES_SAMPLER={{ .Values.otel.traces.sampler.name }}
    export OTEL_TRACES_SAMPLER_ARG={{ .Values.otel.traces.sampler.arg }}

    export OTEL_SERVICE_NAME=groot
    export OTEL_RESOURCE_ATTRIBUTES=service.name=groot,service.version=1.0.0
    export OTEL_TRACES_EXPORTER=otlp
    export OTEL_METRICS_EXPORTER=otlp
    export OTEL_LOGS_EXPORTER=otlp

    export OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=DELTA
    export OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=BASE2_EXPONENTIAL_BUCKET_HISTOGRAM
    # export OTEL_EXPORTER_OTLP_COMPRESSION=gzip
    {{- end }}

    {{- if .Values.uptrace.enabled }}
    export UPTRACE_DSN=http://{{ .Values.uptrace.token }}@${{ .Values.uptrace.service }}:14318?grpc=14317
    export OTEL_EXPORTER_OTLP_ENDPOINT=http://{{ .Values.uptrace.service }}:14317
    export OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=${UPTRACE_DSN}
    {{- end }}


    # For core and heap profiling
    # ulimit -c unlimited
    # sudo mkdir -p /apsara/cloud/data/corefile/ && sudo chown -R graphscope:graphscope /apsara/cloud/data/corefile/
    # export _RJEM_MALLOC_CONF=prof:true,lg_prof_interval:29,lg_prof_sample:19,prof_prefix=/tmp
    # export MALLOC_CONF=prof:true,lg_prof_interval:29,lg_prof_sample:19,prof_prefix=/tmp

    export RUST_BACKTRACE=1
    if [ "$ROLE" = "frontend" ]; then
      echo "Starting groot-http Spring Boot service..."
      ${GRAPHSCOPE_HOME}/groot/bin/store_ctl.sh start_http &
    fi
    ${GRAPHSCOPE_HOME}/groot/bin/store_ctl.sh start ${ROLE}  # || sleep infinity
  portal_setup.sh: |-
    #!/bin/bash

    while true
    do
      {{- if .Values.distributed.enabled }}
      export HOST="${INSTANCE_NAME}-graphscope-store-frontend-0.${INSTANCE_NAME}-graphscope-store-frontend-headless"
      {{- else }}
      export HOST="localhost"
      {{- end }}
      export GRPC_PORT=${GROOT_GRPC_PORT}
      export GREMLIN_PORT=${GROOT_GREMLIN_PORT}
      echo "${HOST} ${GRPC_PORT} ${GREMLIN_PORT}"
      cmd="nc -zv ${HOST} ${GREMLIN_PORT}"
      res=$(eval $cmd 2>&1)
      if [[ $res == *succeeded* ]]; then
        # Expected Output is <Connection to localhost (::1) 8182 port [tcp/*] succeeded!>
        break
      fi
      sleep 3
    done

    export CONFIG_FILE=/tmp/coordinator_config.yaml
    echo "coordinator:" > ${CONFIG_FILE}
    echo "  http_port: ${SERVICE_PORT}" >> ${CONFIG_FILE}
    echo "" >> ${CONFIG_FILE}
    echo "launcher_type: hosts" >> ${CONFIG_FILE}
    echo "" >> ${CONFIG_FILE}
    echo "session:" >> ${CONFIG_FILE}
    echo "  instance_id: demo" >> ${CONFIG_FILE}

    python3 -m gscoordinator --config-file ${CONFIG_FILE}
