#!/usr/bin/env bash
#
# Copyright 2016-2024 Confluent Inc.
#
set -eu
if [ "${DEBUG_ENTRYPOINT}" -ne 0 ]; then
  set -xv
fi

if [ -z "$KAFKA_SECRETS_DIR" ]; then _caas_err "KAFKA_SECRETS_DIR is required"; fi
if [ -z "$KAFKA_LOG4J_DIR" ];   then _caas_err "KAFKA_LOG4J_DIR is required";   fi
if [ -z "$KAFKA_CONFIG_DIR" ];  then _caas_err "KAFKA_CONFIG_DIR is required";  fi
if [ -z "$CAAS_POD_ID" ];       then _caas_err "CAAS_POD_ID is required";       fi


export SERVER_PROPS_FILE="${KAFKA_CONFIG_DIR}/kafka.properties"
if [ -f "${SERVER_PROPS_FILE}" ]; then
  echo "Server properties file was already generated (by init container): ${SERVER_PROPS_FILE}"
else
  echo "Server properties file was not yet created...generating it: ${SERVER_PROPS_FILE}"
  cat "${KAFKA_CONFIG_DIR}/shared/server-common.properties" > "${SERVER_PROPS_FILE}"
  # Make sure there's a new line between the files, so we won't concat lines together
  echo >> "${SERVER_PROPS_FILE}"
  cat "${KAFKA_CONFIG_DIR}/pod/${CAAS_POD_ID}/server-pod.properties" >> "${SERVER_PROPS_FILE}"
fi

export SSLCERTS_DIR="/mnt/sslcerts"
export SSLCERTS_SPEC_FILE="${SSLCERTS_DIR}/spec.json"

export FIPS_ENABLED="false"
if grep -q "ssl.provider=BCJSSE" "${SERVER_PROPS_FILE}" && \
        grep -q "confluent.security.bc.approved.mode.enable=true" "${SERVER_PROPS_FILE}"; then

    echo "Broker is set to FIPS mode!"

    export FIPS_ENABLED="true"
    SSLCERTS_SPEC_FILE="${SSLCERTS_DIR}/specPem.json"

    if [ ! -f "${SSLCERTS_SPEC_FILE}" ]; then
        _caas_err "${SSLCERTS_SPEC_FILE} was not found on a cluster in FIPS mode"
    fi
fi

echo "Trying to use ${SSLCERTS_SPEC_FILE} spec file for SSL configuration"

if [ "$FIPS_ENABLED" = "false" ]; then
    printf "Broker is not set to FIPS mode, resetting paths to NOFIPS\n"
    # Source: https://github.com/confluentinc/lobo-cc-java21/blob/master/cc-java.sh
    # To avoid issues coming from trailing spaces when we try to replace fips options with non-fips options
    # Below is a robust substitution to handle the switching from fips options to non-fips options for JDK_JAVA_OPTIONS and CLASSPATH
    # Example with below replace logic:
    # 1. CLASSPATH=/fips JAVA_FIPS_CLASSPATH=/fips ==> ''
    # 2. CLASSPATH=/foo:/fips JAVA_FIPS_CLASSPATH=/fips ==> /foo
    # 3. CLASSPATH=/fips:/bar JAVA_FIPS_CLASSPATH=/fips ==> /bar
    # 4. CLASSPATH=/foo:/fips:/bar JAVA_FIPS_CLASSPATH=/fips ==> /foo:/bar

    # Strip any of the FIPS options from the JDK_JAVA_OPTIONS, replacing with JAVA_NOFIPS_OPTIONS
    JDK_JAVA_OPTIONS="${JDK_JAVA_OPTIONS:-}"
    if [ "${JDK_JAVA_OPTIONS}" == "${JAVA_FIPS_OPTIONS}" ]; then
      JDK_JAVA_OPTIONS=""
    else
      JDK_JAVA_OPTIONS="${JDK_JAVA_OPTIONS// ${JAVA_FIPS_OPTIONS} / }"
      JDK_JAVA_OPTIONS="${JDK_JAVA_OPTIONS/#${JAVA_FIPS_OPTIONS} /}"
      JDK_JAVA_OPTIONS="${JDK_JAVA_OPTIONS/% ${JAVA_FIPS_OPTIONS}/}"
    fi
    if [ -n "${JAVA_NOFIPS_OPTIONS}" ]; then
      printf "Switching JDK_JAVA_OPTIONS from FIPS option to NOFIPS option\n"
      JDK_JAVA_OPTIONS="${JAVA_NOFIPS_OPTIONS}${JDK_JAVA_OPTIONS:+ ${JDK_JAVA_OPTIONS}}"
    else
      echo "no JAVA_NOFIPS_OPTIONS to substitute\n"
    fi
    export JDK_JAVA_OPTIONS
    # Strip any of the FIPS classpath entries from the CLASSPATH, replacing with JAVA_NOFIPS_CLASSPATH
    CLASSPATH="${CLASSPATH:-}"
    # shellcheck disable=SC2153
    if [ "${CLASSPATH}" == "${JAVA_FIPS_CLASSPATH}" ]; then
      CLASSPATH=""
    else
      CLASSPATH="${CLASSPATH//:${JAVA_FIPS_CLASSPATH}:/:}"
      CLASSPATH="${CLASSPATH/#${JAVA_FIPS_CLASSPATH}:/}"
      CLASSPATH="${CLASSPATH/%:${JAVA_FIPS_CLASSPATH}/}"
    fi
    if [ -n "${JAVA_NOFIPS_CLASSPATH}" ]; then
      printf "Switching CLASSPATH from FIPS path to NOFIPS path\n"
      CLASSPATH="${JAVA_NOFIPS_CLASSPATH}${CLASSPATH:+:${CLASSPATH}}"
    else
      #FEDRAMP-5740: as of writing the code, there is no JAVA_NOFIPS_CLASSPATH to substitute in lobo-cc-jdk21-fips base image
      echo "no JAVA_NOFIPS_CLASSPATH to substitute\n"
    fi
    export CLASSPATH
    # Remove the AWS FIPS environment variable
    unset AWS_USE_FIPS_ENDPOINT
fi

export JDK_JAVA_OPTIONS="${JDK_JAVA_OPTIONS}"
export CLASSPATH="${CLASSPATH}"
printf "FIPS/NOFIPS option checkpoint: JDK_JAVA_OPTIONS now is set to %s\n" "$JDK_JAVA_OPTIONS"
printf "FIPS:NOFIPS option checkpoint: CLASSPATH is now it set to %s\n" "$CLASSPATH"

if [ -e "${SSLCERTS_SPEC_FILE}" ]; then
    KEYSTORE_LOCATION="${SSLCERTS_DIR}"/$(jq -r '.ssl_keystore_filename' "${SSLCERTS_SPEC_FILE}")
    KEYSTORE_TYPE=$(jq -r '.ssl_certificate_encoding' "${SSLCERTS_SPEC_FILE}")
else
    # This block will never get executed in approved mode (FIPS), as we check for the existance of SSLCERTS_SPEC_FILE above.
    # But better safe then sorry:
    if [ "$FIPS_ENABLED" = "true" ]; then
        _caas_err "We shouldn't get here: FIPS_ENABLED is ${FIPS_ENABLED} but ${SSLCERTS_SPEC_FILE} doesn't exists"
    fi

    KEYSTORE_LOCATION="${SSLCERTS_DIR}/pkcs.p12"
    KEYSTORE_TYPE="PKCS12"
    echo "WARNING: ${SSLCERTS_SPEC_FILE} not found, defaulting to ${KEYSTORE_LOCATION} as PKCS12 keystore"
fi

if [ -z "$KEYSTORE_LOCATION" ]; then _caas_err "KEYSTORE_LOCATION is required"; fi
if [ -z "$KEYSTORE_TYPE" ];     then _caas_err "KEYSTORE_TYPE is required";     fi

export KEYSTORE_LOCATION
export KEYSTORE_TYPE
echo "===> Using keystore: KEYSTORE_LOCATION=$KEYSTORE_LOCATION, KEYSTORE_TYPE=$KEYSTORE_TYPE"

# kafka.properties has markers named $KEYSTORE_LOCATION and $KEYSTORE_TYPE.
# the code below will substitute the keystore location and type found above
# for these markers.
sed -i -e 's@${KEYSTORE_LOCATION}@'"$KEYSTORE_LOCATION"'@' -e 's@${KEYSTORE_TYPE}@'"$KEYSTORE_TYPE"'@' "${SERVER_PROPS_FILE}"
rc=$?; if [[ $rc != 0 ]]; then _caas_err "sed failed for KEYSTORE_LOCATION and KEYSTORE_TYPE"; fi

# TODO - final configs need to go in a writable scratch directory
cat ${KAFKA_CONFIG_DIR}/shared/log4j.properties >  /opt/caas/config/kafka/log4j.properties
echo >> /opt/caas/config/kafka/log4j.properties
cat ${KAFKA_CONFIG_DIR}/pod/${CAAS_POD_ID}/log4j.properties >> /opt/caas/config/kafka/log4j.properties
cat ${KAFKA_CONFIG_DIR}/shared/disk-usage-agent.properties >  /opt/caas/config/kafka/disk-usage-agent.properties
cat ${KAFKA_CONFIG_DIR}/shared/jvm.config > /opt/caas/config/kafka/jvm.config
echo >> /opt/caas/config/kafka/jvm.config
cat ${KAFKA_CONFIG_DIR}/pod/${CAAS_POD_ID}/jvm.config >> /opt/caas/config/kafka/jvm.config
cp /opt/caas/templates/jmx-exporter.yaml.j2 /opt/caas/config/jmx-exporter.yaml
cp /opt/caas/templates/otel-javaagent.properties /opt/caas/config/otel-javaagent.properties
