#!/bin/bash

#
# FusionAuth environment setup. The fusionauth.properties file
# is parsed by this script to setup additional command-line properties including memory settings.
#

# Fail on any command failure
set -e

FUSIONAUTH_PLUGIN_DIR=${CATALINA_HOME}/../../plugins
FUSIONAUTH_CONFIG_DIR=${CATALINA_HOME}/../../config
JAVA_DIR=${CATALINA_HOME}/../../java
FUSIONAUTH_LOG_DIR=${CATALINA_HOME}/../../logs
CATALINA_OUT=${FUSIONAUTH_LOG_DIR}/fusionauth-app.log
CATALINA_OPTS="-Dfusionauth.home.directory=$CATALINA_HOME/.. -Dfusionauth.config.directory=$FUSIONAUTH_CONFIG_DIR -Dfusionauth.log.directory=$FUSIONAUTH_LOG_DIR -Dfusionauth.plugin.directory=$FUSIONAUTH_PLUGIN_DIR"
# Required by MySQLHelper.downloadMySQLConnector -> ClassLoaderTools.addURL -> java.net.URLClassLoader.invoke
# --add-opens=java.base/java.net=ALL-UNNAMED"
JAVA_OPTS=" -Djava.awt.headless=true -Dcom.sun.org.apache.xml.internal.security.ignoreLineBreaks=true --add-exports=java.base/sun.security.x509=ALL-UNNAMED --add-exports=java.base/sun.security.util=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED"
JAVA_OPTS=$(echo "${JAVA_OPTS}" | tr -d '\r')

CURL_OPTS="-fSL --progress-bar"
# If we are in a non interactive shell then hide the progress but show errors
if ! tty -s; then
  CURL_OPTS="-sSL"
fi

if [[ ! -d "${CATALINA_HOME}/logs" ]]; then
  mkdir -p "${CATALINA_HOME}/logs"
fi

if [[ ! -d ${JAVA_DIR} ]]; then
  mkdir -p "${JAVA_DIR}"
fi

if [[ ! -d ${FUSIONAUTH_LOG_DIR} ]]; then
  mkdir -p "${FUSIONAUTH_LOG_DIR}"
fi

downloadJava() {
  # Declare the version and the platform and arch dependant URLs
  JAVA_VERSION=17.0.1+12
  BASE_URL_PATH=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.1%2B12/
  Linux_aarch64_Filename=OpenJDK17U-jdk_aarch64_linux_hotspot_17.0.1_12.tar.gz
  Linux_x86_64_Filename=OpenJDK17U-jdk_x64_linux_hotspot_17.0.1_12.tar.gz
  Darwin_x86_64_Filename=OpenJDK17U-jdk_x64_mac_hotspot_17.0.1_12.tar.gz
  Darwin_arm64_Filename=OpenJDK17U-jdk_aarch64_mac_hotspot_17.0.1_12.tar.gz

  # Build a the URL
  OS=$(uname -s)
  ARCH=$(uname -m)
  FILENAME="${OS}_${ARCH}_Filename"
  DOWNLOAD_URL="${BASE_URL_PATH}${!FILENAME}"

  # Ensure both the 'current' and 'jdk-${JAVA_VERSION}' exist, this tells us Java is setup and at the correct version
  if [[ ! -e "${JAVA_DIR}/current" || ! -d "${JAVA_DIR}/jdk-${JAVA_VERSION}" ]]; then
    if [[ "${OS}" = "Darwin" ]]; then
      if [[ -e ~/dev/java/current17 ]]; then
        # Development, just sym link to our current version of Java, because only 'current' will exist in dev, we'll always rebuild the symlink.
        cd "${JAVA_DIR}"
        rm -f current
        # Use the same version that we'll be packaging with Docker during development
        ln -s ~/dev/java/current17-jlinked current
      else
        curl ${CURL_OPTS} "${DOWNLOAD_URL}" -o "${JAVA_DIR}/openjdk-macos-${JAVA_VERSION}.tar.gz"
        tar xfz "${JAVA_DIR}/openjdk-macos-${JAVA_VERSION}.tar.gz" -C "${JAVA_DIR}"
        cd "${JAVA_DIR}"
        rm -f current
        ln -s jdk-${JAVA_VERSION}/Contents/Home current
        rm openjdk-macos-${JAVA_VERSION}.tar.gz
      fi
    elif [[ "${OS}" = "Linux" ]]; then
      curl ${CURL_OPTS} "${DOWNLOAD_URL}" -o "${JAVA_DIR}/openjdk-linux-${JAVA_VERSION}.tar.gz"
      tar xfz "${JAVA_DIR}/openjdk-linux-${JAVA_VERSION}.tar.gz" -C "${JAVA_DIR}"
      cd "${JAVA_DIR}"
      rm -f current
      ln -s jdk-${JAVA_VERSION} current
      rm openjdk-linux-${JAVA_VERSION}.tar.gz
    fi
  fi
}

appendToVariable() {
  local varName=$1
  local value=$2
  if [[ -n ${!varName} ]]; then
    export "${varName}"="${!varName} ${value}"
  else
    export "${varName}"="${value}"
  fi
}

# Arguments are: (envVarName, cmdOption, oldName, newName, oldEnvName, newEnvName)
resolveConfigurationProperty() {
  local envVarName=$1
  local cmdOption=$2
  local oldName=$3
  local newName=$4
  local oldEnvName=$5
  local newEnvName=$6

  if [[ -n ${!newEnvName} ]]; then
    appendToVariable "${envVarName}" "${cmdOption}${!newEnvName}"
    return
  elif [[ -n ${oldEnvName} && -n ${!oldEnvName} ]]; then
    echo "You are using a deprecated environment variable of [${oldEnvName}]. The new variable name is [${newEnvName}]"
    appendToVariable "${envVarName}" "${cmdOption}${!oldEnvName}"
    return
  elif [[ -f "${FUSIONAUTH_CONFIG_DIR}/fusionauth.properties" ]]; then
    if [[ -n ${newName} ]]; then
      newValue=$(grep "^${newName//[.]/\.}" "${FUSIONAUTH_CONFIG_DIR}/fusionauth.properties" | tr -d '\r' | cut -d'=' -f2-)
      if [[ -n ${newValue} ]]; then
        appendToVariable "${envVarName}" "${cmdOption}${newValue}"
        return
      fi
    fi
    if [[ -n ${oldName} ]]; then
      oldValue=$(grep "^${oldName//[.]/\.}" "${FUSIONAUTH_CONFIG_DIR}/fusionauth.properties" | tr -d '\r' | cut -d'=' -f2-)
      if [[ -n ${oldValue} ]]; then
        echo "You are using a deprecated configuration property of [${oldName}] in [fusionauth.properties]. The new variable name is [${newName}]"
        appendToVariable "${envVarName}" "${cmdOption}${oldValue}"
        return
      fi
    fi
  fi
}

if [[ ${FUSIONAUTH_USE_GLOBAL_JAVA} != 1 ]]; then
  # Download Java if necessary
  downloadJava

  # Set JAVA_HOME
  JAVA_HOME=${JAVA_DIR}/current
fi

resolveConfigurationProperty JAVA_OPTS -Dfusionauth-app.http.port= fusionauth-app.http-port fusionauth-app.http.port FUSIONAUTH_HTTP_PORT FUSIONAUTH_APP_HTTP_PORT
resolveConfigurationProperty JAVA_OPTS -Dfusionauth-app.https.port= fusionauth-app.https-port fusionauth-app.https.port FUSIONAUTH_HTTPS_PORT FUSIONAUTH_APP_HTTPS_PORT
resolveConfigurationProperty JAVA_OPTS -Dfusionauth-app.ajp.port= fusionauth-app.ajp-port fusionauth-app.ajp.port FUSIONAUTH_AJP_PORT FUSIONAUTH_APP_AJP_PORT
resolveConfigurationProperty JAVA_OPTS -Dfusionauth-app.management.port= fusionauth-app.management-port fusionauth-app.management.port FUSIONAUTH_MANAGEMENT_PORT FUSIONAUTH_APP_MANAGEMENT_PORT
resolveConfigurationProperty CATALINA_OPTS -Xmx "" fusionauth-app.memory FUSIONAUTH_MEMORY FUSIONAUTH_APP_MEMORY
resolveConfigurationProperty CATALINA_OPTS -Xms "" fusionauth-app.memory FUSIONAUTH_MEMORY FUSIONAUTH_APP_MEMORY
resolveConfigurationProperty CATALINA_OPTS "" "" fusionauth-app.additional-java-args FUSIONAUTH_ADDITIONAL_JAVA_ARGS FUSIONAUTH_APP_ADDITIONAL_JAVA_ARGS
resolveConfigurationProperty JAVA_OPTS -Dfusionauth-app.http.cookie.same-site-policy= fusionauth-app.cookie-same-site-policy fusionauth-app.http.cookie.same-site-policy FUSIONAUTH_COOKIE_SAME_SITE_POLICY FUSIONAUTH_APP_HTTP_COOKIE_SAME_SITE_POLICY
resolveConfigurationProperty JAVA_OPTS -Dfusionauth-app.http.max-header-size= fusionauth-app.http-max-header-size fusionauth-app.http.max-header-size FUSIONAUTH_HTTP_MAX_HEADER_SIZE FUSIONAUTH_APP_HTTP_MAX_HEADER_SIZE
resolveConfigurationProperty JAVA_OPTS -Dfusionauth-app.http.relaxed-path-chars= "" fusionauth-app.http.relaxed-path-chars "" FUSIONAUTH_APP_HTTP_RELAXED_PATH_CHARS
resolveConfigurationProperty JAVA_OPTS -Dfusionauth-app.http.relaxed-query-chars= "" fusionauth-app.http.relaxed-query-chars "" FUSIONAUTH_APP_HTTP_RELAXED_QUERY_CHARS
