#!/bin/bash
SOURCE="$0"
source /usr/lib/elive-tools/functions
EL_REPORTS="1"
el_make_environment
. gettext.sh
TEXTDOMAIN="elive-tools"
export TEXTDOMAIN

# Lock system (good one) {{{
lockfile="/tmp/.$(basename $0)-${USER}.lock"

exit_ok(){
    rm -f "$lockfile"
}
exit_error(){
    rm -f "$lockfile"
}

if [[ -r "$lockfile" ]] ; then
    PROCCESS="$(cat $lockfile)"
else
    PROCCESS=" "
fi
if (ps up $PROCCESS) 1>/dev/null 2>&1 ; then
    el_error "$(basename $0) already running"
    exit
else
    echo $$ > "$lockfile"
fi

# traps needs to be after the lock verification, in order to not remove it when we are already running
trap "exit_ok" EXIT
trap "exit_error" 1 3 5 6 14 15 ERR TERM

# SET the lock file
echo "$$" > "$lockfile"


# end lock system }}}

do_list(){
    local mode pass already_run line
    mode="$1"
    pass="$2"

    sync

    # run them:
    if test -s "$order_file" ; then
        while read -ru 3 line
        do
            unset executable cmd pid
            read -r line <<< "$line"

            # skip comments
            if [[ "$line" = "#"* ]] || [[ -z "$line" ]] ; then
                continue
            fi

            # skip already runs:
            if el_array_member_check "$line" "${already_run[@]}" ; then
                continue
            fi

            # parse and get info
            case "$line" in
                *.desktop|*.DESKTOP)
                    if [[ -s "$line" ]] ; then
                        cmd="$( grep "^Exec=" "$line" | sed -e 's|^Exec=||g' -e 's|%.*$||g' | tail -1 )"
                        executable="$( echo "$cmd" | awk '{print $1}' )"
                    fi

                    ;;
                *)
                    cmd="$line"
                    executable="$( echo "$line" | awk '{print $1}')"
                    ;;
            esac

            # get the correct name of the command to use:
            case "$executable" in
                sudo|*bash|*zsh*|*perl*|*ruby*|*sh)
                    # note: in the case of the sudo commands, we cannot get the pid because it doesn't belongs to us, in any case, is simply wrong to run things on sudo so there's no issues with this
                    for arg in $cmd
                    do
                        if ! echo "$arg" | grep -qsiE "^(sudo|*bash|*zsh*|*perl*|*ruby*|*sh|\-.*)$" ; then
                            if [[ -x "$( which "$arg" )" ]] ; then
                                el_debug "fix: executable set to '$arg' instead of '$executable' "
                                executable="$arg"
                                break
                            fi
                        fi
                    done
                    ;;
                *)
                    ;;
            esac

            # check and report to user
            if ! [[ -x "$( which "$executable" )" ]] && ! [[ -x "$executable" ]] ; then
                unable_executable="$executable"
                if [[ -z "$unable_executable" ]] ; then
                    unable_executable="$cmd"
                fi
                if [[ -z "$unable_executable" ]] ; then
                    unable_executable="$line"
                fi

                local message_unable_title
                message_unable_title="$( printf "$( eval_gettext "Unable to run an autostart application" )" "" )"
                local message_unable_description
                message_unable_description="$( printf "$( eval_gettext "An autostart application failed to run. You must install it or remove it from your startup list:" )" "" )"

                notify-send -e -u critical -t 14000 -i gnome-searchtool "$message_unable_title" "$message_unable_description\n\n~/.e16/startup-applications.list\n\nFAILED: ${unable_executable}"

                # next!
                continue
            fi

            # start or stop them
            if [[ -n "$cmd" ]] && [[ -n "$executable" ]] ; then

                case "$mode" in
                    start)
                        # close other instances, just in case
                        killall "$(basename "$executable" )"  2>/dev/null || true
                        killall -9 "$(basename "$executable" )"  2>/dev/null || true

                        el_debug "running: $cmd"
                        bash -c "$cmd  & disown"
                        ;;

                    stop)
                        pid="$( ps kstart_time uxf | grep -v "grep .*$cmd" | grep -F "$cmd" | awk '{print $2}' | tail -1 )"
                        if [[ -z "$pid" ]] ; then
                            pid="$( ps kstart_time uxf | grep -v "grep .*$executable" | grep -F "$executable" | awk '{print $2}' | tail -1 )"
                        fi

                        if [[ -z "$pid" ]] ; then
                            continue
                        fi

                        #if [[ -n "$pid" ]] ; then
                            #el_debug "pid $pid for $executable :  $cmd"
                        #fi

                        # first pass
                        case "$pass" in
                            first)
                                if ps --no-headers -p "$pid" 1>/dev/null 2>&1 ; then
                                    kill "$pid"  2>/dev/null
                                    LC_ALL=C sleep 0.2

                                    # if ! ps --no-headers -p "$pid" 1>/dev/null 2>&1 ; then
                                    #     el_debug "killed successfully (first pass): $cmd"
                                    # fi
                                fi
                                ;;
                            second)

                                # still running? force it
                                if ps --no-headers -p "$pid" 1>/dev/null 2>&1 ; then
                                    kill -9 "$pid"  2>/dev/null
                                    LC_ALL=C sleep 0.3

                                    if ps --no-headers -p "$pid" 1>/dev/null 2>&1 ; then
                                        sync ; LC_ALL=C sleep 0.3
                                        if ps --no-headers -p "$pid" 1>/dev/null 2>&1 ; then
                                            el_error "unable to kill with -9, WTF?: ex: '$executable' , cmd '$cmd', pid '$pid':\n$(ps -p "$pid" 2>&1 )"
                                        fi
                                    # else
                                    #     el_debug "killed successfully (SECOND pass): $cmd"
                                    fi
                                fi
                                ;;
                            *)
                                el_error "dafuck $mode $pass"
                                ;;
                        esac
                        ;;
                esac
            fi

            # append to the already run list:
            el_array_member_add "$line" "${already_run[@]}" ; already_run=("${_out[@]}")

        done 3<<< "$( cat "$order_file" )"
    fi

}

main(){
    # Usage
    if [[ -z "${1}" ]] ; then
        echo -e "Usage: $(basename $BASH_SOURCE) [start|stop]"
        echo -e "Runs the XDG autostart applications selected by the user"
        exit 1
    fi

    mode="$1"
    pass="$2"

    if [[ -n "$EROOT" ]] ; then
        # e16
        order_file="$HOME/.e16/startup-applications.list"
        e_version="0.16"
    else

        if [[ -x "$(which enlightenment)" ]] ; then
            if [ -n "$E_START" ] && [ -z "$E_HOME_DIR" ] ; then
                E_HOME_DIR="$HOME/.e/e17"
            fi
            order_file="$E_HOME_DIR/applications/startup/.order"
        else
            el_error "unknown version of Enlightenment, ignoring selection of startup applications: '$E_VERSION' "
            exit
        fi

        #     e_version="$( enlightenment --version | grep "^Version: " | sed -e 's|^Version: ||g' | tail -1 )"
        #     case "$e_version" in
        #         0.17.*)
        #             order_file="$HOME/.e/e17/applications/startup/.order"
        #             ;;
        #         *)
        #             el_error "unknown version of Enlightenment, ignoring selection of startup applications: '$E_VERSION' "
        #             exit
        #             ;;
        #     esac
        # fi
    fi

    if ! [[ -e "$order_file" ]] ; then
        el_info "This tool requires a list of startup applications, located in '$order_file' "
        el_info "This file is a plain text list containing the full address of the .desktop files to run"
        el_info "example: /etc/xdg/autostart/elive-upgrader.desktop "
        exit 1
    fi

    case "$mode" in
        start)
            do_list "start"
            ;;
        stop)
            do_list "stop" first
            do_list "stop" second
            ;;
        *)
            el_error "unknown mode for $SOURCE"
            ;;
    esac

}

#
#  MAIN
#
main "$@"

# vim: set foldmethod=marker :
