#!/bin/bash

realPath() {
    path=$1
    target=$(readlink "${path}")

    while [ -n "${target}" ]; do
        path=$(cd $(dirname "${path}") && cd $(dirname "${target}") && pwd -P)/$(basename "${target}")
        target=$(readlink ${path})
    done

    if [ -d "${path}" ]; then
        path=$(cd "${path}" && pwd -P)
    elif [ -f "${path}" ]; then
        path=$(cd $(dirname "${path}") && pwd -P)/$(basename "${path}")
    fi

    echo "${path}"
}

self=$(realPath "$0")
dir=$(dirname "${self}")
name=$(basename "${self}")

cmd="${dir}/.${name}"
if [ ! -x "${cmd}" ]; then
    echo "$0: ${cmd} does not exist" >&2
    exit 1
fi

# set up java modules for Hazelcast
if [ -z "${JAVA_HOME}" ]; then
  if ( ! which java > /dev/null 2>&1 ); then
      echo "$0: could not find Java" >&2
      exit 1
  fi
  java='java'

else
  java="${JAVA_HOME}/bin/java"
  if [ ! -x ${java} ]; then
    java="${JAVA_HOME}/jre/sh/java"
    if [ ! -x ${java} ]; then
      echo "$0: could not find Java" >&2
      exit 1
    fi
  fi
fi

java_version=$( ${java} -version 2>&1 | grep version | cut -d'"' -f 2 | cut -d'.' -f 1,2 )
if [ ${java_version} = '1.8' ]; then
  java_version=8
elif [ $(echo ${java_version} | cut -d'.' -f 1) = '11' ]; then
  java_version=11
fi

# setup hazelcast logging and java modules
if [ ${java_version} != 8 ] && [ ${java_version} != 11 ]; then
  echo "$0: Java ${java_version} is currently not supported, please use Java 8 or 11"
elif (( ${java_version} > 8 )); then
  export BC_SERVER_OPTS="-Dprogram.name=${name} -Dhazelcast.logging.type=log4j2 --add-modules java.se --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED"
else
  export BC_AGENT_OPTS="program.name=${name} -Dhazelcast.logging.type=log4j2"
fi

forceStartFile='/tmp/bc-server.force.start'
if [ -f ${forceStartFile} ]; then
    export BEYONDCRON_FORCE_START=true
    rm ${forceStartFile}
    if [ $? -ne 0 ]; then
        echo "$0: could not delete force start file ${forceStartFile}" >&2
        exit 1
    fi
fi

if [ -n "${BEYONDCRON_ALERT_COMMAND}" ]; then
    alertCmd=${BEYONDCRON_ALERT_COMMAND}

    aCmd=$(echo "${alertCmd}" | cut -d' '  -f1)
    if [ ! -x "${aCmd}" ]; then
        echo "$0: alert command ${aCmd} does not exist" >&2
        exit 1
    fi
fi

stopSignal=${BEYONDCRON_SIGNAL_STOP:-WINCH}
if [ $(kill -l | grep -c ${stopSignal}) -ne 1 ]; then
  echo "$0: unknown stop signal ${stopSignal}, using WINCH instead" >&2
  stopSignal=$(kill -l WINCH)
elif [[ ! "$stopSignal" =~ ^[0-9]+$ ]]; then
  stopSignal=$(kill -l $stopSignal)
fi

termSignal=$(kill -l TERM)

trapSignal=0
trap 'echo "$0: stopping ${name} after receiving signal INT" >&2; trapSignal=${termSignal}; kill -TERM $childPid; ' INT
trap 'echo "$0: stopping ${name} after receiving signal TERM" >&2; trapSignal=${termSignal}; kill -TERM $childPid' TERM
trap 'echo "$0: shutting down ${name}"; trapSignal=${stopSignal}; kill -${stopSignal} $childPid' ${stopSignal}
trap '' HUP USR1 USR2

${cmd} "$@" &
childPid=$!
wait $childPid
result=$?
code=$(($result & 127))

while [ $result -ge 128 -a $code -eq $trapSignal ]; do
  trapSignal=0
  wait $childPid
  result=$?
  code=$(($result & 127))
done

if [ $result -ge 128 -a $code -eq $stopSignal ]; then
  code=0
fi

if [ ${code} -ne 0 ]; then
  export BEYONDCRON_DAEMON=${name}
  export BEYONDCRON_EXIT_CODE=${code}
  export BEYONDCRON_OS_USER=$(id -un)
  export BEYONDCRON_ALERT_REASON="${name} stopped after receiving signal ${code}"

  echo "$0: ${BEYONDCRON_ALERT_REASON}" >&2

  if [ -n "${alertCmd}" ]; then
    eval "${alertCmd}"
  fi

  if [ $result -ge 128 ]; then
    code=2
  fi

else
  echo "${name} shutdown"
fi

exit ${code}

# end