#!/bin/sh
#-*-Mode:sh;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*-
# ex: set ft=sh fenc=utf-8 sts=4 ts=4 sw=4 et nomod:

# script location
SCRIPT=`basename $0`
SCRIPT_PATH=`dirname $0`

# Name of the running pid (argv[0])
PID_NAME="$SCRIPT"
# Name of this file
PROGNAME="$SCRIPT"

ROOTDIR=`cd $SCRIPT_PATH/.. && pwd`
START_ERL_DATA="$ROOTDIR/releases/start_erl.data"
ERLANG_ERTS_VERSION=`cat $START_ERL_DATA | awk '{print $1}'`
RELEASE_VERSION=`cat $START_ERL_DATA | awk '{print $2}'`
BINDIR="$ROOTDIR/erts-$ERLANG_ERTS_VERSION/bin"
EMU=beam
RELEASEDIR="$ROOTDIR/releases/$RELEASE_VERSION"
ROOT_BIN_DIR="$ROOTDIR/bin"
ROOT_ETC_DIR="$ROOTDIR/etc"
ROOT_LOG_DIR="$ROOTDIR/logs"
PROGNAME_FILE="$ROOT_BIN_DIR/$PROGNAME"
VMARGS_FILE="$ROOT_ETC_DIR/vm.args"
ERLCONFIG_FILE="$ROOT_ETC_DIR/app.config"
TMPDIR="/tmp/$PROGNAME"
PIPE_DIR="$TMPDIR/shell/"
CLOUDI_PID_FILE="$ROOT_LOG_DIR/$PROGNAME.pid"

# based on TIMEOUT_TERMINATE_MAX in cloudi_core_i_constants.hrl (milliseconds)
SHUTDOWN_TIME_MAX=65000

# Create epmd command-line
EPMD="$BINDIR/epmd -daemon"

# Create nodetool command-line
NODETOOL="$BINDIR/escript $ROOT_BIN_DIR/nodetool"

# Common erl command-line arguments enforced on any vm.args file use
VMARGS="-mode embedded -shutdown_time $SHUTDOWN_TIME_MAX"

cd "$ROOTDIR"

# Ensure epmd is running
$EPMD
if [ $? -ne 0 ]; then
    echo "EPMD failed to start!"
    exit 1
fi

case "$1" in
    start|start_boot)
        # Make sure there is not already a node running
        $NODETOOL test
        if [ $? -eq 0 ]; then
            echo "Node is already running!"
            exit 1
        fi
        case "$1" in
            start)
                shift
                START_OPTION="console"
                HEART_OPTION="start"
                ;;
            start_boot)
                shift
                START_OPTION="console_boot"
                HEART_OPTION="start_boot"
                ;;
        esac
        # CloudI run_erl logging settings
        export RUN_ERL_LOG_ACTIVITY_MINUTES="5"    # 5 minutes (default)
        export RUN_ERL_LOG_ALIVE_MINUTES="15"      # 15 minutes (default)
        export RUN_ERL_LOG_ALIVE_IN_UTC="1"
        export RUN_ERL_LOG_ALIVE_FORMAT="%Y-%m-%dT%H:%M:%SZ"
        export RUN_ERL_LOG_GENERATIONS="128"
        export RUN_ERL_LOG_MAXSIZE="536870912"
        export RUN_ERL_DISABLE_FLOWCNTRL="true"
        # OS process name created by run_erl
        export ESCRIPT_NAME="$PID_NAME"
        # CloudI environment variable settings
        export TMPDIR

        RUN_PARAM="'$@'"
        export HEART_COMMAND="$PROGNAME_FILE $HEART_OPTION $RUN_PARAM"
        rm -rf "$TMPDIR"
        mkdir "$TMPDIR"
        chmod 700 "$TMPDIR"
        mkdir "$PIPE_DIR"
        chmod 700 "$PIPE_DIR"
        $BINDIR/run_erl -daemon "$PIPE_DIR" "$ROOT_LOG_DIR" "exec $PROGNAME_FILE $START_OPTION $RUN_PARAM" 2>&1
        ;;
    stop)
        # Wait for the node to completely stop...
        $NODETOOL stop
        EXIT=$?
        if [ $EXIT -ne 0 ]; then
            exit $EXIT
        fi
        if [ ! -f "$CLOUDI_PID_FILE" ]; then
            exit 1
        fi
        PID=`cat "$CLOUDI_PID_FILE"`
        while `kill -0 "$PID" 2>/dev/null`;
        do
            sleep 1
        done

        # Remove the pid file
        rm -f "$CLOUDI_PID_FILE"
        # Remove temporary data directory
        rm -rf "$TMPDIR"
        ;;
    restart)
        # Restart the VM without exiting the process
        $NODETOOL restart
        exit $?
        ;;
    reboot)
        # Restart the VM completely (uses heart to restart it)
        $NODETOOL reboot
        exit $?
        ;;
    test)
        # Test if the VM is alive without any output
        $NODETOOL test
        exit $?
        ;;
    ping)
        # See if the VM is alive
        $NODETOOL ping
        exit $?
        ;;
    attach)
        # Make sure a node IS running
        $NODETOOL test
        if [ $? -ne 0 ]; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        exec "$BINDIR/to_erl" "$PIPE_DIR"
        ;;
    remote_console)
        # Make sure a node IS running
        REMSH=`$NODETOOL args_remsh`
        if [ $? -ne 0 ]; then
            echo "Node is not running!"
            exit 1
        fi
        CMD="$BINDIR/erl $REMSH"

        shift
        exec $CMD
        ;;
    console|console_clean|console_boot)
        # .boot file typically just $PROGNAME (ie, the app name)
        # however, for debugging, sometimes start_clean.boot is useful.
        # For e.g. 'setup', one may even want to name another boot script.
        case "$1" in
            console)        BOOTFILE=$PROGNAME ;;
            console_clean)  BOOTFILE=start_clean ;;
            console_boot)
                shift
                BOOTFILE="$1"
                shift
                ;;
        esac
        # Setup beam-required vars
        CMD="$BINDIR/erlexec -boot $RELEASEDIR/$BOOTFILE -config $ERLCONFIG_FILE -args_file $VMARGS_FILE $VMARGS"
        export EMU
        export ROOTDIR
        export BINDIR
        export PROGNAME

        # Dump the environment info to the console log
        echo "Exec: $CMD" -- ${1+"$@"}
        echo "Root: $ROOTDIR"

        # Store the pid
        echo $$ > "$CLOUDI_PID_FILE"

        # Start the VM
        exec $CMD -- ${1+"$@"}
        ;;
    foreground)
        # start up the release in the foreground for use by runit
        # or other supervision services
        FOREGROUND_ARGS="-noinput +Bd"

        # Setup beam-required vars
        CMD="$BINDIR/erlexec $FOREGROUND_ARGS -boot $RELEASEDIR/$PROGNAME -config $ERLCONFIG_FILE -args_file $VMARGS_FILE $VMARGS"
        export EMU
        export ROOTDIR
        export BINDIR
        export PROGNAME

        # Dump the environment info to the console log
        echo "Exec: $CMD" -- ${1+"$@"}
        echo "Root: $ROOTDIR"

        # Not using the pid file
        rm -f "$CLOUDI_PID_FILE"

        # Start the VM
        exec $CMD -- ${1+"$@"}
        ;;
    *)
        echo "Usage: $PROGNAME {start|start_boot <file>|foreground|stop|restart|reboot|test|ping|console|console_clean|console_boot <file>|attach|remote_console}"
        exit 1
        ;;
esac

