#!/bin/bash
# GENERATED ON {{ application.buildDate }}

ETC_FOLDER="{{ folders.etc }}"
DATA_FOLDER="{{ folders.data }}"
LIB_FOLDER="{{ folders.lib }}"
TEMP_FOLDER="{{ folders.temp }}"
HPROF_FOLDER="{{ folders.hprofFolder }}"

LOG_FOLDER="{{ log.folder }}"
LOG_FILE="$LOG_FOLDER/{{ log.file }}"
LOG_CONFIG="{{ log.configFileName }}"
GC_LOG_PATH="$LOG_FOLDER/{{ log.gcLogFileName }}"
SH_LOG_PATH="$LOG_FOLDER/{{ log.shLogFileName }}"

{% if deploy.mode == "qloud" %}
HOST_NAME=$QLOUD_HOSTNAME
{% else %}
HOST_NAME=`/bin/hostname -f`
{% endif %}

{% if deploy.mode == "qloud" %}
if [ -z "$ENVIRONMENT_TYPE" ]; then
    if [ -z "$QLOUD_ENVIRONMENT" ]; then
        echo "Failed to get environment type"
        exit 1
    else
        ENVIRONMENT_TYPE="$QLOUD_ENVIRONMENT"
    fi
fi
{% else %}
ENVIRONMENT_TYPE=`cat /etc/yandex/environment.type`
{% endif %}

APP_NAME="{{ application.project }}-{{ application.module }}"

[ -e "$ETC_FOLDER/deployment.$ENVIRONMENT_TYPE.json" ] && DEPLOYMENT_CONFIG="deployment.$ENVIRONMENT_TYPE.json"

# Debug and monitoring
JMX_MONITORING_ENABLED="{{ "true" if jmx.enabled else "false" }}"
DEBUG_ENABLED="{{ "true" if debug.enabled else "false" }}"
DEBUG_SUSPEND_ON_START="false"
PROFILING_ENABLED="{{ "true" if profiling.enabled else "false" }}"

while getopts ":dspj" option
do
    case $option in
        p  ) PROFILING_ENABLED="true" ;;
        d  ) DEBUG_ENABLED="true" ;;
        s  ) DEBUG_SUSPEND_ON_START="true" ;;
        j  ) JMX_MONITORING_ENABLED="true" ;;
        \? ) echo "Unknown option: -$OPTARG" >&2; exit 1;;
        :  ) echo "Missing option argument for -$OPTARG" >&2; exit 1;;
        *  ) echo "Unimplimented option: -$OPTARG" >&2; exit 1;;
    esac
done

shift $(($OPTIND - 1))

# Default Java options
MAIN_CLASS="{{ java.mainClass }}"

JAVA_XMS="{{ java.xms }}"
JAVA_XMX="{{ java.xmx }}"

CLASSPATH="$LIB_FOLDER/*"
JAVA_LIBRARY_PATH="$LIB_FOLDER:/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib"

{% if java.version == "17" %}
JAVA=/usr/local/jdk-17/bin/java
{% elif java.version == "11" %}
JAVA=/usr/local/jdk-11/bin/java
{% elif java.version == "8" %}
JAVA=/usr/local/java8/bin/java
{% elif java.version == "7" %}
JAVA=/usr/local/java7/bin/java
{% elif java.version == "6" %}
JAVA=/usr/local/java6/bin/java
{% else %}
echo "Warning: JDK version not configured, try to use default"
if [ -n "$JAVA_HOME" -a -e $JAVA_HOME/bin/java ]; then
    JAVA=$JAVA_HOME/bin/java
fi
{% endif %}

if [ ! -f "$JAVA" ]; then
    echo "Java not found and JAVA_HOME not set"
    exit 1
fi

# Options overrides
[ -e "{{ folders.bin }}/start.options.sh" ] && . {{ folders.bin }}/start.options.sh

# Debug and profiling are alternative options
if [ $DEBUG_ENABLED == "true" ]; then
{%- if debug.port is not defined %}
if [ true ]; then echo "Warning: Debug port is not configured"; else
{%- endif %}
    _DEBUG_SUSPEND="n"
    [ "$DEBUG_SUSPEND_ON_START" == "true" ] && _DEBUG_SUSPEND="y"
    DEBUG_PORT="{{ debug.port }}"
    DEBUG_OPTIONS="$DEBUG_OPTIONS -agentlib:jdwp=transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=$_DEBUG_SUSPEND"
{%- if debug.port is not defined %}
fi
{%- endif %}

elif [ $PROFILING_ENABLED == "true" ]; then
{%- if profiling.agentPath is not defined %}
if [ true ]; then echo "Warning: Profiling port is not configured"; else
{%- endif %}
    PROFILING_AGENT_PATH="{{ profiling.agentPath }}"
    PROFILING_OPTIONS="{{ profiling.options }}"
    DEBUG_OPTIONS="$DEBUG_OPTIONS \
 -agentpath:$PROFILING_AGENT_PATH=$PROFILING_OPTIONS \
"
{%- if profiling.agentPath is not defined %}
fi
{%- endif %}
fi

if [ $JMX_MONITORING_ENABLED == "true" ]; then
{%- if jmx.port is not defined %}
if [ true ]; then echo "Warning: JMX port is not configured"; else
{%- endif %}
    # Get first ipv4 address
    HOST_IPV4=`hostname -I | tr ' ' '\n' | grep -E -m 1 -o '[0-9]+(\.[0-9]+){3}'`
    HOST_IPV6=`hostname -I | tr ' ' '\n' |  grep -E -m 1 -o '[0-9a-h]+(:[0-9a-h]*)+'`
    if [ "$HOST_IPV4" ]; then
      HOST_IP="$HOST_IPV4"
    else
      HOST_IP="$HOST_IPV6"
    fi
    JMX_MONITORING_PORT="{{ jmx.port }}"
    # JMX by default is called using RMI, which is starts DGC
    # configure DGC to triggers Full GC every 48 hours
    if [ "$HOST_IP" ]; then
      DEBUG_OPTIONS="$DEBUG_OPTIONS \
 -Dcom.sun.management.jmxremote \
 -Dcom.sun.management.jmxremote.port=$JMX_MONITORING_PORT \
 -Dcom.sun.management.jmxremote.authenticate=false \
 -Dcom.sun.management.jmxremote.ssl=false \
 -Dsun.rmi.dgc.client.gcInterval=172800000 \
 -Dsun.rmi.dgc.server.gcInterval=172800000 \
 -Djava.rmi.server.hostname=$HOST_IP \
"
   else
     echo "Host ip could not be found, JMX disabled: `hostname -I`"
   fi
{%- if jmx.port is not defined %}
fi
{%- endif %}
fi

# Application start options
COMMON_APPLICATION_PROPERTIES="\
 -Dcommon.project.name={{ application.project }} \
 -Dcommon.module.name={{ application.module }} \
 -Dcommon.version={{ application.version }} \
 -Dcommon.revision={{ application.repositoryRevision }} \
 -Dcommon.builddate={{ application.buildDate }} \
 -Dcommon.hostname=$HOST_NAME \
 -Dcommon.log.folder=$LOG_FOLDER \
 -Dcommon.log.file=$LOG_FILE \
 -Dcommon.log.config=$LOG_CONFIG \
 -Dcommon.etc.folder=$ETC_FOLDER \
 -Dcommon.data.folder=$DATA_FOLDER \
 -Dcommon.temp.folder=$TEMP_FOLDER \
 -Dmodule.name=$APP_NAME \
 -Dapplication.startup.config.json={{ folders.bin ~ "/application.json" }} \
 -Dapplication.startup.log.config=$LOG_CONFIG \
 -Dapplication.startup.environment=$ENVIRONMENT_TYPE \
 -Dapplication.startup.hostname=$HOST_NAME \
"

{% if deploy.mode == "qloud" %}
COMMON_APPLICATION_PROPERTIES="$COMMON_APPLICATION_PROPERTIES\
 -Ddeployment.qloud.cpu.guarantee=$QLOUD_CPU_GUARANTEE \
 -Ddeployment.qloud.cpu.limit=$QLOUD_CPU_LIMIT \
 -Ddeployment.qloud.cpu.cores=$QLOUD_CPU_CORES \
 -Ddeployment.qloud.peers=$QLOUD_PEERS \
 -Ddeployment.qloud.dc=$QLOUD_DATACENTER \
 -Ddeployment.qloud.environment=$QLOUD_ENVIRONMENT \
 -Ddeployment.qloud.port=$QLOUD_HTTP_PORT \
"
{% endif %}

{% if java.version == "17" %}
COMMON_APPLICATION_PROPERTIES="$COMMON_APPLICATION_PROPERTIES\
--add-opens java.base/sun.net.dns=ALL-UNNAMED \
--add-opens java.base/sun.nio.ch=ALL-UNNAMED \
--add-opens java.base/java.io=ALL-UNNAMED \
--add-opens java.base/java.nio=ALL-UNNAMED \
--add-opens java.base/sun.security.action=ALL-UNNAMED \
"
{% endif %}

[ -n "$DEPLOYMENT_CONFIG" ] && COMMON_APPLICATION_PROPERTIES="$COMMON_APPLICATION_PROPERTIES\
 -Dcommon.deployment.config=$DEPLOYMENT_CONFIG
"

# Overrides temporary disabled
# [ -e "{{ folders.bin }}/start.override.sh" ] && . {{ folders.bin }}/start.override.sh

echo "Set en_EN.UTF-8 locale" >> $SH_LOG_PATH
export LANG=en_EN.UTF-8

echo "$JAVA \
 -server\
 -showversion\
 -Dfile.encoding=UTF-8\
 -Doracle.net.tns_admin=/etc/oracle\
 -Xms${JAVA_XMS}\
 -Xmx${JAVA_XMX}\
 {%- if (java.useG1GC is sameas true) or (java.version == "17") %}
 -XX:+UseG1GC \
 {%- else %}
 -XX:+UseConcMarkSweepGC \
 {%- endif %}
 {%- if (java.version == "11") or (java.version == "17") %}
  -Xlog:gc*:file=$GC_LOG_PATH \
  {%- else %}
 -Xloggc:$GC_LOG_PATH \
 -XX:+PrintGCDetails \
 -XX:+PrintGCDateStamps \
 {%- endif %}
 -XX:-OmitStackTraceInFastThrow\
 -XX:+HeapDumpOnOutOfMemoryError\
 -XX:HeapDumpPath=$HPROF_FOLDER\
 -XX:+CrashOnOutOfMemoryError\
 $COMMON_APPLICATION_PROPERTIES\
 $DEBUG_OPTIONS\
{%- for option in java.options -%}
{%- if java.options[option] is none %}
 {{ option }} \
{%- else %}
 {{ option }}={{ java.options[option] }} \
{%- endif -%}
{% endfor %}
 $CUSTOM_JAVA_OPTIONS \
 -classpath $CLASSPATH \
 -Djava.library.path=$JAVA_LIBRARY_PATH \
 $MAIN_CLASS $*" {% if log.redirectOutput %}>> $SH_LOG_PATH {% endif %}

exec -a "$APP_NAME" $JAVA \
 -server \
 -showversion \
 -Dfile.encoding=UTF-8 \
 -Doracle.net.tns_admin=/etc/oracle \
 -Xms${JAVA_XMS} \
 -Xmx${JAVA_XMX} \
  {%- if (java.useG1GC is sameas true) or (java.version == "17") %}
 -XX:+UseG1GC \
 {%- else %}
 -XX:+UseConcMarkSweepGC \
 {%- endif %}
 {%- if (java.version == "11") or (java.version == "17") %}
 --illegal-access=debug \
 -Xlog:gc*:file=$GC_LOG_PATH \
 {%- else %}
 -Xloggc:$GC_LOG_PATH \
 -XX:+PrintGCDetails \
 -XX:+PrintGCDateStamps \
 {%- endif %}
 -XX:-OmitStackTraceInFastThrow \
 -XX:+HeapDumpOnOutOfMemoryError \
 -XX:HeapDumpPath=$HPROF_FOLDER\
 -XX:+CrashOnOutOfMemoryError \
 $COMMON_APPLICATION_PROPERTIES \
 $DEBUG_OPTIONS \
{%- for option in java.options -%}
{%- if java.options[option] is none %}
 {{ option }} \
{%- else %}
 {{ option }}="{{ java.options[option] }}" \
{%- endif -%}
{% endfor %}
 $CUSTOM_JAVA_OPTIONS \
 -classpath "$CLASSPATH" \
 -Djava.library.path=$JAVA_LIBRARY_PATH \
 $MAIN_CLASS $* {% if log.redirectOutput %}>> $SH_LOG_PATH 2>&1{% endif %}
