#!/bin/bash
#  Name:     ubl-exec-app
#  Purpose:  Perform appropriate startup of ubl-exec-app executable apps.
#
#
#  Copyright (C) 2026 UBLinux
#
#  This file is part of UBLinux.
#
#  ubl-exec-app is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  ubinstall-gtk is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with GParted.  If not, see <http://www.gnu.org/licenses/>.
#

APP_NAME=${BASH_SOURCE[0]##*/}
if [[ "${APP_NAME}" =~ (.*)"-root"$ ]]; then
    GRANTED_USER="root"
    APP_NAME="${BASH_REMATCH[1]}"
elif [[ "${APP_NAME}" =~ (.*)"-user"$ ]]; then
    GRANTED_USER="user"
    APP_NAME="${BASH_REMATCH[1]}"
else
    exit 0
fi

arguments(){
    # Pre-process options to:
    # - expand -xyz into -x -y -z
    # - expand --longopt=arg into --longopt arg
    local ARGV=()
    local END_OF_OPT=
    while [[ $# -gt 0 ]]; do
        ARG="$1"; shift
        case "${END_OF_OPT}${ARG}" in
            --)         ARGV+=("${ARG}"); END_OF_OPT=1 ;;
            --*=*)      ARGV+=("${ARG%%=*}" "${ARG#*=}") ;;
            --*)        ARGV+=("${ARG}") ;;
            -*)         for i in $(seq 2 ${#ARG}); do ARGV+=("-${ARG:i-1:1}"); done ;;
            *)          ARGV+=("${ARG}") ;;
        esac
    done
    # Apply pre-processed options
    set -- "${ARGV[@]}"

    # Parse options
    local POSITIONAL_ARGS=()
    local END_OF_OPT=
    while [[ $# -gt 0 ]]; do
        case "${END_OF_OPT}${1}" in
            --setenv)   shift; SET_ARGS_APP+=("${1%%=*}=${1#*=}") ;;
            -d | --debug) DEBUG=yes; POSITIONAL_ARGS+=("$1") ;;
            --)         END_OF_OPT=1 ;;
            -*|--*)     POSITIONAL_ARGS+=("$1") ;;
            *)          POSITIONAL_ARGS+=("$1") ;;
        esac
        shift
    done
    # Restore positional parameters
    set -- "${POSITIONAL_ARGS[@]}"
    REQUEST_ARGS=("${POSITIONAL_ARGS[@]}")
}

check_env(){
    if [[ ${XDG_SESSION_TYPE} == "wayland" && ${XDG_CURRENT_DESKTOP} == "KDE" ]]; then
        ENV_ARGS+=("--disable-gtksocket")
    elif [[ ${XDG_SESSION_TYPE} == "wayland" ]]; then
        ENV_ARGS+=("--setenv GDK_BACKEND=x11")
    fi
}

    #  Only permit one instance of ubl-exec-app to execute at a time
    if pidof ${BASH_SOURCE[0]##*/} 1> /dev/null; then
        echo "The process ${BASH_SOURCE[0]##*/} is already running."
        echo "Only one ${BASH_SOURCE[0]##*/} process is permitted."
        exit 1
    fi

    #  Define base command for executing app
    BASE_CMD="/usr/bin/${APP_NAME}"
    ENV_ARGS=()
    DEBUG=

    #  For non-root users try to get authorisation to run app as root.
    if [[ "x$(id -u)" != "x0" && ${GRANTED_USER} == "root" ]]; then
        # Get user environment
        for SELECT_ENV in "DISPLAY" "XAUTHORITY" "WAYLAND_DISPLAY" "XDG_RUNTIME_DIR" "XDG_SESSION_TYPE" "XDG_SESSION_DESKTOP" "XDG_CURRENT_DESKTOP"; do
            #if [[ -n ${!SELECT_ENV} && ${SELECT_ENV} == "WAYLAND_DISPLAY" && -n ${XDG_RUNTIME_DIR} ]]; then
                #ENV_ARGS+=("--setenv WAYLAND_DISPLAY=${XDG_RUNTIME_DIR}/${!SELECT_ENV}")
            if [[ -n ${!SELECT_ENV} ]]; then
                ENV_ARGS+=("--setenv ${SELECT_ENV}=${!SELECT_ENV}")
            fi
        done
        check_env

        #  If there is no configured SU program run app as
        #  non-root to display the graphical error about needing root
        #  privileges.
        #
        if test "xpkexec --disable-internal-agent" = "x"; then
                echo "Root privileges are required for running $0."
                ${BASE_CMD}
                exit 1
        fi

        # Interim workaround to allow app run by root access to the
        # X11 display server under Wayland.  The xhost command is
        # available and root has not been granted access to the X11
        # display via xhost, then grant access.
        ENABLE_XHOST_ROOT=yes
        GRANTED_XHOST_ROOT=no
        if test "x${ENABLE_XHOST_ROOT}" = 'xyes' && xhost 1> /dev/null 2>&1; then
            if ! xhost | grep -qi 'SI:localuser:root$'; then
                xhost +SI:localuser:root
                GRANTED_XHOST_ROOT=yes
            fi
        fi

        # Run app as root.
        [[ $@ =~ ("-d"|"--debug") ]] && echo -e "\npkexec --disable-internal-agent ${BASH_SOURCE[0]} ${ENV_ARGS[@]} $@"
        pkexec --disable-internal-agent ${BASH_SOURCE[0]} ${ENV_ARGS[@]} $@
        STATUS=$?

        # Revoke root access to the X11 display, only if we granted it.
        if test "x${GRANTED_XHOST_ROOT}" = 'xyes'; then
            xhost -SI:localuser:root
        fi
        exit ${STATUS}
    elif [[ ${GRANTED_USER} == "user" ]]; then
        check_env
    fi

    SET_ARGS_APP=(); REQUEST_ARGS=(); arguments "$@"; set -- "${REQUEST_ARGS[@]}"

    if [[ ${#SET_ARGS_APP[@]} -gt 0 ]]; then
        [[ -n ${DEBUG} ]] && echo -e "\nexport ${SET_ARGS_APP[@]}"
        export "${SET_ARGS_APP[@]}"
    fi

    if [[ ${GRANTED_USER} == "root" ]]; then
        export UBL_EXEC_APP="${USER}::${BASE_CMD} $@"
        [[ -n ${DEBUG} ]] && echo -e "\n${USER}::${BASE_CMD} $@"
        ${BASE_CMD} $@
    elif [[ ${GRANTED_USER} == "user" ]]; then
        export UBL_EXEC_APP="${USER}::${BASE_CMD} ${ENV_ARGS[@]} $@"
        [[ -n ${DEBUG} ]] && echo -e "\n${USER}::${BASE_CMD} ${ENV_ARGS[@]} $@"
        ${BASE_CMD} ${ENV_ARGS[@]} $@
    fi

    STATUS=$?
    exit ${STATUS}
