#!/bin/sh

###############################################
# CONFIGURATION
###############################################

INSTALL_DIR="/opt/oxibackup"

if ! . "$INSTALL_DIR/etc/oxibackupd/service.conf" >/dev/null 2>&1
then
    >&2 echo "Could not load service configuration file"
    exit 1
fi

SERVICE_CONTROL="$INSTALL_DIR/bin/oxibackupd-control"
SERVICE_EXEC="$INSTALL_DIR/bin/oxibackupd-service"
SERVICE_FULL_NAME="Oxibox backup agent"

# Find out if we must use 'echo' or 'echo -e' to display tabs and line breaks
if echo "\n" | grep -q '\\n' > /dev/null 2>&1
then
    ECHO_ESCAPE_CMD="echo -e"
else
    ECHO_ESCAPE_CMD="echo"
fi

###############################################
# FUNCTIONS
###############################################

show_help () {
    echo "$SERVICE_FULL_NAME service control"
    echo "Available commands:"
    $ECHO_ESCAPE_CMD "\tstart\tStart the service now"
    $ECHO_ESCAPE_CMD "\tstop\tStop running service instance, service will restart if still enabled"
    $ECHO_ESCAPE_CMD "\trestart\tRestart the service"
    $ECHO_ESCAPE_CMD "\tstatus\tShow service status"
    $ECHO_ESCAPE_CMD "\tenable\tEnable the service if it was disabled, service will start itself as scheduled"
    $ECHO_ESCAPE_CMD "\tdisable\tDisable the service"
    $ECHO_ESCAPE_CMD "\thelp\tShow this help message"
}

list_processes () {
    ps axo pid,lstart,args | grep "$INSTALL_DIR/bin/oxibackupd" | grep -v -e grep -e opkg -e prerm -e control | awk -F ' ' '{print $1}' | tr '\n' ' '
}

# Kill PIDS with SIGKILL or KILL signals
force_kill () {
    kill -n 9 $@ > /dev/null 2>&1
}

restart_cron () {
    if [ -e /usr/syno/sbin/synoservicectl ] # Syno
    then
        if ! /usr/syno/sbin/synoservicectl --restart crond > /dev/null 2>&1
        then
            report_cron_error "$1"
        fi
    elif [ -e /etc/init.d/crond.sh ] # QNAP
    then
        if ! /etc/init.d/crond.sh restart > /dev/null 2>&1
        then
            report_cron_error "$1"
        fi
    elif [ -e /etc/init.d/crond ]
    then
        if ! /etc/init.d/crond restart > /dev/null 2>&1
        then
            report_cron_error "$1"
        fi
    elif [ -e /etc/init.d/cron ]
    then
        if ! /etc/init.d/cron restart > /dev/null 2>&1
        then
            report_cron_error "$1"
        fi
    elif [ -e /etc/rc.d/cron ]
    then
        if ! /etc/rc.d/cron restart > /dev/null 2>&1
        then
            report_cron_error "$1"
        fi
    else
        if ! service crond restart > /dev/null 2>&1
        then
            if ! service cron restart > /dev/null 2>&1
            then
                if ! systemctl restart crond.service > /dev/null 2>&1
                then
                    >&2 echo "Couldn't find any cron service"
                    report_cron_error "$1"
                fi
            fi
        fi
    fi
}

report_cron_error () {
    >&2 echo "An error occurred while trying to restart cron service"
    # If service was just enabled, disable it to clean cron tasks since we can't restart the cron service to apply changes
    if [ "$1" = "enable" ]
    then
        disable_service "NO_RESTART"
    fi
    exit 1
}

start_service () {
    echo "Starting service..."
    nohup "$SERVICE_EXEC" > /dev/null 2>&1 &
    echo "Service started ($!)"
}

stop_service () {
    echo "Stopping service..."
    OTHER_PID="$(cat "${PID_FILE}" 2>/dev/null)"
    if [ ! -z "$OTHER_PID" ]
    then
        # This command returns exit code 0 if PID is empty and run through /bin/sh
        # Only execute if we know OTHER_PID is not empty
        if kill -0 $OTHER_PID > /dev/null 2>&1
        then
            PROC_GROUP_ID=$(ps -p $OTHER_PID -o pgid= | tr -d ' ')
            kill -n 15 -$PROC_GROUP_ID > /dev/null 2>&1
            sleep 2
            REMAINING_PIDS="$(list_processes)"
            if [ ! -z "$REMAINING_PIDS" ]
            then
                echo "Forcing service processes to stop..."
                force_kill $REMAINING_PIDS
            fi
            echo "Service stopped"
        else
            echo "Service is not running"
        fi
    else
        echo "Service is not running"
    fi
}

service_status () {
    SERVICE_ENABLED=0
    if command -v crontab >/dev/null 2>&1
    then
        if crontab -l | grep -q "$SERVICE_CONTROL"
        then
            SERVICE_ENABLED=1
        fi
    elif grep -q "$SERVICE_CONTROL" /etc/crontab
    then
        SERVICE_ENABLED=1
    fi

    SERVICE_RUNNING=0
    OTHER_PID="$(cat "${PID_FILE}" 2>/dev/null)"
    if [ ! -z "$OTHER_PID" ]
    then
        # This command returns exit code 0 if PID is empty and run through /bin/sh
        # Only execute if we know OTHER_PID is not empty
        if kill -0 $OTHER_PID  > /dev/null 2>&1
        then
            SERVICE_RUNNING=1
        fi
    fi

    echo "$SERVICE_FULL_NAME service status"
    echo -n "Enabled: "
    if [ $SERVICE_ENABLED -eq 1 ]
    then
        echo "yes"
    else
        echo "no"
    fi
    echo -n "Running: "
    if [ $SERVICE_RUNNING -eq 1 ]
    then
        echo "yes"
    else
        echo "no"
    fi
}

enable_service () {
    echo "Enabling service..."
    if command -v crontab >/dev/null 2>&1 # crontab command available
    then
        if ! crontab -l | grep -q "$SERVICE_CONTROL"
        then
            (crontab -l ; echo "* * * * * $SERVICE_CONTROL start > /dev/null") | crontab -
        fi
        if [ -e /etc/config/crontab ] # indestructible crontab, survives QTS reboots
        then
            crontab -l > /etc/config/crontab
        fi
        echo "Service successfully enabled"
    elif [ -f /etc/crontab ]
    then
        if ! grep -q "$SERVICE_CONTROL" /etc/crontab # Use /etc/crontab
        then
            $ECHO_ESCAPE_CMD "*\t*\t*\t*\t*\troot\t$SERVICE_CONTROL start > /dev/null" >> /etc/crontab
            restart_cron enable
        fi
        echo "Service successfully enabled"
    else
        >&2 echo "Couldn't find a way to add a cron job"
        exit 1
    fi
}

disable_service () {
    echo "Disabling service..."
    if command -v crontab >/dev/null 2>&1
    then
        if crontab -l | grep -q "$SERVICE_CONTROL start"
        then
            (crontab -l | grep -v "$SERVICE_CONTROL start") | crontab -
        fi
        if [ -e /etc/config/crontab ] # indestructible crontab, survives QTS reboots
        then
            crontab -l > /etc/config/crontab
        fi
        echo "Service successfully disabled"
    elif [ -f /etc/crontab ]
    then
        if grep -q "$SERVICE_CONTROL start" /etc/crontab
        then
            sed "\@$SERVICE_CONTROL start@d" -i /etc/crontab
            if [ "$1" != "NO_RESTART" ]
            then
                restart_cron disable
            fi
        fi
        echo "Service successfully disabled"
    else
        >&2 echo "Couldn't find a way to modify cron job"
        exit 1
    fi
}

###############################################
# SERVICE CONTROL
###############################################

if [ $# -ne 1 ]
then
    >&2 echo "Wrong number of arguments"
    show_help
    exit 1
fi

case "$1" in
    "start")
        start_service
    ;;
    "stop")
        stop_service
    ;;
    "status")
        service_status
    ;;
    "restart")
        stop_service
        start_service
    ;;
    "enable")
        enable_service
    ;;
    "disable")
        disable_service
    ;;
    "help")
        show_help
    ;;
    *)
        >&2 echo "Unknown command $1"
        show_help
        exit 1
    ;;
esac

exit 0
