#!/bin/sh
set -e
set -u

# eturnal STUN/TURN server.
#
# Copyright (c) 2020-2023 Holger Weiss <holger@zedat.fu-berlin.de>.
# Copyright (c) 2020-2023 ProcessOne, SARL.
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# CONFIGURATION SECTION:

user="${ETURNAL_USER:-eturnal}"
prefix="${ETURNAL_PREFIX:-/opt/eturnal}"
etc_dir="${ETURNAL_ETC_DIR:-/etc}"
epmd_address="${ERL_EPMD_ADDRESS:-127.0.0.1}"
dist_port="${ERL_DIST_PORT:-}"
code_loading="${CODE_LOADING_MODE:-static}"
config_file="${etc_dir:-/etc}/eturnalctl.cfg"

# END OF CONFIGURATION SECTION.

unsupported='credentials
  upgrade
  downgrade
  install
  uninstall
  unpack
  versions'

edit_my_name()
{
    sed -e "s/^Usage: eturnal/Usage: ${0##*/}/" \
        -e '/No cookie is set or found/d'
}

usage()
{
    _cmd="$1"

    "$_cmd" 'help' | edit_my_name | grep -v -F "$unsupported"
    cat <<-'EOF'
	  reload                  Reload eturnal's configuration
	  info                    Print some details regarding the running node
	  sessions [Username]     Print TURN sessions(s) belonging to given [Username]
	  disconnect [Username]   Close TURN session(s) belonging to given [Username]
	  credentials [E[U] [S]]  Print credentials derived from the configured secret
	  password [Username]     Print the password for the given [Username]
	  loglevel [Level]        Get or set the current log [Level]
	  version                 Print eturnal's version string
	EOF
}

find_eturnal_yml()
{
    set -- \
        "$(printf '%s' "$*" | sed -n 's/.*-conf file "\([^"][^"]*\)".*/\1/p')" \
        "${etc_dir:-/etc}/eturnal.yml" \
        "$release_dir/etc/eturnal.yml" \
        '/dev/null'

    for path in "$@"
    do
        if [ -e "$path" ]
        then
            printf '%s' "$path"
            return
        fi
    done
}

get_option()
{
    _key="$1"
    _val=$(sed -n \
        "s/^[[:blank:]]\\{1,\\}$_key:[[:blank:]]*\"\\?\\([[:alnum:][:blank:]\\/._+-]*[[:alnum:]\\/._+-]\\)\"\\?.*/\\1/p" \
        "$eturnal_yml" 2>'/dev/null' || :)

    printf '%s' "$_val"
}

myself="$(readlink -f "$0" || printf '%s' "$0")"
release_dir="$(cd "$(dirname "$myself")/.." && pwd -P)"
eturnal_yml="$(find_eturnal_yml "$@")"
log_dir="$(get_option 'log_dir')"

if [ -e "$config_file" ]
then
    . "$config_file"
fi

if [ -z "${ETURNAL_ETC_DIR+x}" ] && [ -n "$etc_dir" ]
then
    ETURNAL_ETC_DIR="$etc_dir"
    export ETURNAL_ETC_DIR
fi
if [ -z "${ERL_EPMD_ADDRESS+x}" ] && [ -n "$epmd_address" ]
then
    ERL_EPMD_ADDRESS="$epmd_address"
    export ERL_EPMD_ADDRESS
fi
if [ -z "${ERL_DIST_PORT+x}" ] && [ -n "$dist_port" ]
then
    ERL_DIST_PORT="$dist_port"
    export ERL_DIST_PORT
fi
if [ -z "${CODE_LOADING_MODE+x}" ] && [ "$code_loading" = 'dynamic' ]
then
    CODE_LOADING_MODE='interactive'
    export CODE_LOADING_MODE
fi
if [ -z "${RUNNER_LOG_DIR+x}" ]
then
    if [ -n "$log_dir" ] && [ "$log_dir" != 'stdout' ]
    then
        RUNNER_LOG_DIR="$log_dir"
        export RUNNER_LOG_DIR
    elif [ -n "${LOGS_DIRECTORY:-}" ]
    then
        RUNNER_LOG_DIR="$LOGS_DIRECTORY"
        export RUNNER_LOG_DIR
    fi
fi

if [ -x "$prefix/bin/eturnal" ]
then
    cmd="$prefix/bin/eturnal"
elif [ -x "$release_dir/bin/eturnal" ]
then
    cmd="$release_dir/bin/eturnal"
else
    cmd='eturnal' # Rely on $PATH.
fi

if [ $# -eq 0 ] || [ "$1" = '-h' ] || [ "$1" = '--help' ] || [ "$1" = 'help' ]
then
    if [ $# -gt 1 ]
    then
        "$cmd" "$@" | edit_my_name
    else
        usage "$cmd"
    fi
elif [ "$(id -u)" = '0' ] && [ "$user" != 'root' ]
then
    cd '/'
    arg="$(printf '%s' "$*" | sed 's/[^[:alnum:][:space:]]/\\&/g')"
    case $(uname -s) in
        Linux|OpenBSD)
            s_opt='-s /bin/sh'
            ;;
        *)
            s_opt=''
            ;;
    esac
    exec su $s_opt "$user" -c "exec $cmd $arg"
else
    exec "$cmd" "$@"
fi
