#!/bin/bash

################################################################################
# Copyright (C) 2012-2026 NICE s.r.l.
# All Rights Reserved
#
# This software is the confidential and proprietary information
# of NICE s.r.l. ("Confidential Information").
# You shall not disclose such Confidential Information
# and shall use it only in accordance with the terms of
# the license agreement you entered into with NICE.
################################################################################

log () { echo "$@" >&2; }

restore_file () {
    local file=$1
    local backup=$2
    local marker=$3

    local tmp=$(mktemp)
    cp -a "$file" "$backup"

    # copy the file to preserve permissions
    cp -a "$file" "$tmp"

    local res=0
    # store file stripped of DCV modifications
    if ! sed -e "/^\ *#\ BEGIN-${marker}$/, /^\ *#\ END-${marker}$/ {d;}" "$tmp" > "$file"; then
        res=$?
        log "Could not restore script '$file'"
    fi

    rm -f "$tmp"
    return $res
}

AWK_CONFIGURE_SCRIPT='
function add_dcvxgrantaccess() {
    print "# BEGIN-" MARKER
    print "# Added by nice-dcv on " DATE ", please do not touch."
    print "if (PATH=$PATH:/usr/sbin; ! command -v dcvgladmin || ! dcvgladmin status) > /dev/null; then"
    print "    dcvxgrantaccess +dcv"
    print "else"
    print "    dcvxgrantaccess"
    print "fi"
    print "# END-" MARKER
}

BEGIN {
    DONE=0
    SKIP=0
}

# Skip other sections added by this script
DONE==0 && /^# BEGIN-/ {
    SKIP=1
}

SKIP==1 && /^# END-/ {
   SKIP=0
}

# Search for first line which is not 1) empty or 2) a #comment
DONE==0 && SKIP==0 && /^[ \t]*$|^[ \t]*[^#]/ {
    add_dcvxgrantaccess()
    DONE=1
}

{
    print $0
}

END {
    if (DONE == 0) {
        add_dcvxgrantaccess()
    }
}
'

configure_file () {
    local file=$1
    local backup=$2
    local marker=$3

    if ! restore_file "$file" "$backup" "$marker"; then
        return 1
    fi

    # add DCV custom stanza
    local tmp=$(mktemp)

    # copy the file to preserve permissions
    cp -a "$file" "$tmp"

    local res=0
    if ! cat "$tmp" |\
            awk -v DATE="$(date)" -v MARKER="$marker" "$AWK_CONFIGURE_SCRIPT" > "$file"; then
        res=$?
        log "Cannot add configuration to script '$file'"
    fi

    rm -f "$tmp"
    return $res;
}

check_file () { [ -f "$1" -a ! -h "$1" ]; }

check_do_file () {
    local action=$1
    local file=$2
    local marker=$3

    check_file "$file" || return

    if [ $action = configure ]; then
        log "Adding DCV specific customizations to '$file' script..."
    else # $action = restore
        log "Removing DCV specific customizations from '$file' script..."
    fi

    local backup="$file.backup"
    ${action}_file "$file" "$backup" "$marker"

    if command -v diff 2>&1 >/dev/null &&
           diff --ignore-matching-lines='^[ \t]*#' "$file" "$backup" 2>&1 > /dev/null; then
        log "No changes were done"
    fi
}

get_dcv_folder () {
    local dcv_folders="
/usr/libexec/dcv
/usr/lib/$(arch)-linux-gnu/dcv
/usr/lib/dcv
"

    local dcv_folder
    for d in $dcv_folders; do
        if [ -d $d ]; then
            dcv_folder=$d
            break
        fi
    done

    echo $dcv_folder
}

get_lightdm_confd_script () {
    local lightdm_confd_dir=/etc/lightdm/lightdm.conf.d

    # add SLES15 special case
    if [ -d /etc/xdg/lightdm ]; then
        lightdm_confd_dir=/etc/xdg/lightdm/lightdm.conf.d
    fi

    echo $lightdm_confd_dir/50-dcvxgrantaccess.conf
}

get_gdm_greeter_script () { echo "/usr/share/gdm/greeter/autostart/dcv.desktop"; }

configure_dcvxgrantaccess () {
    local marker=$1
    local dcv_folder=$2

    add_dcv_placeholder () {
        local script=$1
        local description=$2

        # generate an empty script placeholder, the actual script is added later
        log "Creating $description script '$script'..."
        echo "#!/bin/bash" > $script
        chmod +x $script
    }

    # On Sles 15 we need to enable X access in the gdm autostart greeter
    local gdm_greeter_script=$(get_gdm_greeter_script)

    if [ -d $(dirname "$gdm_greeter_script") ]; then
        log "Creating GDM greeter script '${gdm_greeter_script}'..."
        cat > $gdm_greeter_script <<EOF
# Automatically generated by dcvxgrantaccessinstaller - do not edit
[Desktop Entry]
Type=Application
Name=DCV_X_grantaccess
Exec=${dcv_folder}/dcvgdm
X-GNOME-Autostart-Phase=Initialization
NoDisplay=true
EOF

        add_dcv_placeholder ${dcv_folder}/dcvgdm GDM
    fi

    local lightdm_dir=/etc/lightdm
    local lightdm_conf_script=${lightdm_dir}/lightdm.conf
    local lightdm_confd_script=$(get_lightdm_confd_script)

    if [ -d $lightdm_dir -a ! -h $lightdm_dir ]; then
        if [ -f $lightdm_conf_script ] && grep -q '^[ ]*display-setup-script' $lightdm_conf_script; then
            log "WARNING: display-setup-script is already defined in $lightdm_conf_script, it will override the setting in $lightdm_confd_script"
        fi

        if [ ! -f $lightdm_confd_script ]; then
            log "Creating lightdm configuration script '$lightdm_confd_script'..."
            cat > ${lightdm_confd_script} <<EOF
# Automatically generated by dcvxgrantaccessinstaller - do not edit
[Seat:*]
display-setup-script=${dcv_folder}/dcvlightdm
EOF

            add_dcv_placeholder ${dcv_folder}/dcvlightdm lightdm
        fi
    fi
}

restore_dcvxgrantaccess () {
    local dcv_folder=$1
    # remove the auto-generated files

    local scripts="$dcv_folder/dcvlightdm $dcv_folder/dcvgdm $(get_lightdm_confd_script) $(get_gdm_greeter_script)"
    local script
    for script in $scripts; do
        if [ -f $script ]; then
            log "Deleting auto-generated script '$script'..."
            rm -f $script
        fi
    done
}

dcvxgrantaccess_install () {
    local help="Install or uninstall all the X configurations for DCV.

Usage:
dcvxgrantaccessinstaller [install|uninstall] [OPTIONS]

Actions:
install           install all the DCV configurations to grant X access
uninstall         uninstall all the DCV configurations to grant X access

If no action is specified, assume install.

Options:
--access-mode | -x MODE set the dcvxgrantaccess mode to set in the configuration files (deprecated)
--help | -h             print this option and exit
--marker | -m MARKER    set marker (deprecated)
"

    local action
    local marker=DCV

    while [ "$1" != "" ]; do
        case "$1" in
            --help | -h )
                echo "$help"
                return 0
                ;;
            --marker | -m )
                shift
                log "WARNING: option --marker '$1' is deprecated and will be ignored"
                ;;
            --access-mode | -x )
                shift
                log "WARNING: option --access-mode '$1' is deprecated and will be ignored"
                ;;
            -* )
                log "Unknown option '$1', use --help for usage instructions"
                break
                ;;
            * )
                if [ -n "$action" ]; then
                    log "Action '$1' was given but action '$action' was already specified, only one can be specified"
                    return 1
                fi
                if [[ $1 =~ ^(install|uninstall)$ ]]; then
                    action=$1
                else
                    log "Invalid action '$1' specified, aborting"
                    return 1
                fi
                ;;
        esac
        shift
    done

    if [ -z "$action" ]; then
        action=install
    fi

    local dcv_folder=$(get_dcv_folder)

    if [ -z "$dcv_folder" ]; then
        log "Cannot find DCV folder, aborting"
        return 1
    fi

    if [ $action = install ]; then
        configure_dcvxgrantaccess "$marker" "$dcv_folder"
    fi

    local conf_files=()
    check_add_file () { check_file "$1" && conf_files+=("$1"); }

    local file
    for file in "${dcv_folder}/dcvgdm" "${dcv_folder}/dcvlightdm" /etc/gdm3/Prime/Default /etc/sddm/Xsetup; do
        check_add_file "$file"
    done

    check_add_file /etc/X11/xdm/Xsetup_0 || check_add_file /etc/X11/xdm/Xsetup
    check_add_file /etc/X11/gdm/Init/:0 || check_add_file /etc/X11/gdm/Init/Default

    # Search for all gdm/Init/Default files in /etc and /usr/local/etc
    for file in $(find /etc /usr/local/etc -xdev -regex ".*/gdm/Init/Default$" 2>/dev/null); do
        check_add_file "$file"
    done

    # Search for all kdm/Xsetup files in /etc, /usr/share and /usr/local/share
    for file in $(find /etc /usr/share /usr/local/share -xdev -regex ".*/kdm/Xsetup$" 2>/dev/null); do
        check_add_file "$file"
    done

    case $action in
        install|uninstall )
            local file_action=$([ $action = install ] && echo configure || echo restore)
            for file in "${conf_files[@]}"; do
                check_do_file $file_action "$file" "$marker"

                # DCV-GL used to install a marker "DCV-GL". Ensure to remove it.
                check_do_file restore "$file" "DCV-GL"
            done
            ;;
    esac

    if [ $action = uninstall ]; then
        restore_dcvxgrantaccess "$dcv_folder"
    fi
}

dcvxgrantaccess_install "$@"

# --------------------------------------------------------------------------- #
# ex: set ts=4 sw=4 et syntax=sh :
# --------------------------------------------------------------------------- #
