#!/bin/bash
set -o errexit -o nounset -o pipefail
function -h {
cat <<USAGE
 USAGE: marathon-framework (--jar <marathon.jar>)? <option>*

  Run the Marathon scheduler, collecting options from the configuration
  directory $conf_dir and configuration file $conf_file,
  and appending the options supplied on the command line.

  If you would like to pass the Jar to be run, do so with --jar. If the Jar is
  not supplied, the script assumes the Jar has been concatenated to it and
  will supply its own path to Java.

USAGE
}; function --help { -h ;}
export LC_ALL=en_US.UTF-8

self="$(cd "$(dirname "$0")" && pwd -P)"/"$(basename "$0")"
marathon_jar="$self"
conf_dir=/etc/marathon/conf
conf_file=/etc/default/marathon

function main {
  if [[ ${1:-} = --jar ]]
  then marathon_jar="$2" ; shift 2
  fi
  load_options_and_log "$@"
}

function element_in {
  local e
  for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
  return 1
}

function load_options_and_log {
  # Call mesosphere-dnsconfig if present on the system to generate config files.
  [ -x /usr/bin/mesosphere-dnsconfig ] && mesosphere-dnsconfig -write -service=marathon

  # Load Marathon options from Mesos and Marathon conf files that are present.
  # Launch main program with Syslog enabled.
  local cmd=( run_jar )
  # Load custom options
  if [[ -d $conf_dir ]]
  then
    while read -u 9 -r -d '' path
    do
      local name="${path#./}"
      if ! element_in "--${name#'?'}" "$@"
      then
        case "$name" in
          '?'*) cmd+=( "--${name#'?'}" ) ;;
          *)    cmd+=( "--$name" "$(cat "$conf_dir/$name")" ) ;;
        esac
      fi
    done 9< <(cd "$conf_dir" && find . -type f -not -name '.*' -print0)
  fi
  # Read environment variables from config file
  set -o allexport
  [[ ! -f "$conf_file" ]] || . "$conf_file"
  set +o allexport
  for env_op in `env | grep ^MARATHON_ | sed -e '/^MARATHON_APP/d' -e 's/MARATHON_//' -e 's/=/ /'| awk '{printf("%s%s ", "--", tolower($1)); for(i=2;i<=NF;i++){printf("%s ", $i)}}'| sed -e 's/ $//'`; do
    cmd+=( "$env_op" )
  done
  # Default zk and master option
  if [[ -s /etc/mesos/zk ]]
  then
    if [[ "${cmd[@]} $@" != *'--zk '* ]]
    then
      cmd+=( --zk "$(cut -d / -f 1-3 /etc/mesos/zk)/marathon" )
    fi
    if [[ "${cmd[@]} $@" != *'--master'* ]]
    then
      cmd+=( --master "$(cat /etc/mesos/zk)" )
    fi
  fi
  echo "${cmd[@]}"

  if [[ "${cmd[@]} $@" =~ .*--no[_-]logger.* ]]
  then
    local clean_cmd=()
    for i in "${cmd[@]}" "$@"; do
      if [[ "${i}" != "--no-logger" ]] && [[ "${i}" != "--no_logger" ]]; then
        clean_cmd+=( "${i}" )
      fi
    done
    "${clean_cmd[@]}"
  else
    logged marathon "${cmd[@]}" "$@"
  fi
}

function run_jar {
  local log_format='%2$s%5$s%6$s%n' # Class name, message, exception

  # if running as root and open file limit less than 8192 raise the limit
  [ $EUID -eq 0 -a $(ulimit -n) -lt 8192 ] && ulimit -n 8192

  export PATH=/usr/local/bin:"$PATH"
  local vm_opts=( -Djava.library.path=/usr/local/lib:/usr/lib:/usr/lib64
                  -Djava.util.logging.SimpleFormatter.format="$log_format" )
  for j_opt in ${JAVA_OPTS:-"-Xmx512m"}; do
    vm_opts+=( ${j_opt} )
  done
  # TODO: Set main class in pom.xml and use -jar
  if [ -n "${JAVA_HOME:=}" ]
    then
      JAVA_BIN="$JAVA_HOME/bin/java"
    else
      JAVA_BIN="java"
  fi
  exec $JAVA_BIN "${vm_opts[@]}" -cp "$marathon_jar" mesosphere.marathon.Main "$@"
}

function logged {
  local token="$1[$$]" ; shift
  exec 1> >(exec logger -p user.info   -t "$token")
  exec 2> >(exec logger -p user.notice -t "$token")
  "$@"
}

function msg { out "$*" >&2 ;}
function err { local x=$? ; msg "$*" ; return $(( $x == 0 ? 1 : $x )) ;}
function out { printf '%s\n' "$*" ;}

if [[ ${1:-} ]] && declare -F | cut -d' ' -f3 | fgrep -qx -- "${1:-}"
then "$@"
else main "$@"
fi
