#!/usr/bin/env bash

ENABLED=yes
[[ ${ENABLED} != "yes" ]] && exit 0
DEBUGMODE=no

SOURCE=/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
SOURCE=/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
debug_mode "$0" "$@"

SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/video; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/desktop; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/keyboard; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null

    [[ ${DISPLAYMANAGER} == "none" ]] && exit 0

    #[ ! -z "$VGAID" ] && grep -q $VGAID /usr/share/ublinux/hwdata/deleteconf && rm -f /etc/X11/xorg.conf
    [[ -n "${DELETE_XORG_CONF}" ]] && rm -f /etc/X11/xorg.conf

exec_vgadrv_auto(){
    # Auto VGA driver loader
    FILE_LIGHTDM_CONF="/etc/lightdm/lightdm.conf.d/01-vgadrv-auto-ubconfig.conf"
    FILE_SRC_NVIDIA_CONF="/usr/lib/ublinux/xorg.conf.d/20-nvidia-ubconfig.conf"
    FILE_TARG_NVIDIA_CONF="/etc/X11/xorg.conf.d/20-vgadrv-auto-ubconfig.conf"

    FILE_SRC_NVIDIA_RULES="/usr/lib/ublinux/udev/70-nvidia-ubconfig.rules"
    FILE_TARG_NVIDIA_RULES="/etc/udev/rules.d/70-vgadrv-auto-ubconfig.rules"
    if [[ -n ${VGADRV_AUTO} ]]; then
        [[ -d /etc/X11/xorg.conf.d ]] || install -Dm755 /etc/X11/xorg.conf.d
	while read LSPCI_DEVICE; do
	    while read KERNEL_MODULE; do
		[[ ${KERNEL_MODULE} != "nouveau" ]] && modprobe ${KERNEL_MODULE} 2>/dev/null && break
	    done < <(lspci -ks ${LSPCI_DEVICE%% *} | grep 'Kernel modules:' | cut -d: -f2 | tr ',' '\n' | tac)
	done < <(lspci | grep -Ei 'vga|3d')
	if lsmod | grep nvidia &>/dev/null; then
	    #[[ -f /usr/bin/nvidia-xconfig ]] && nvidia-xconfig -s --no-logo --no-composite --no-dynamic-twinview --force-generate --output-xconfig=${FILE_TARG_NVIDIA_CONF}
	    [[ -e ${FILE_TARG_NVIDIA_CONF} ]] || ln -sf "${FILE_SRC_NVIDIA_CONF}" "${FILE_TARG_NVIDIA_CONF}"
	    #[[ -e ${FILE_TARG_NVIDIA_RULES} ]] || ln -sf "${FILE_SRC_NVIDIA_RULES}" "${FILE_TARG_NVIDIA_RULES}"
	    /usr/bin/nvidia-modprobe -c0 -umsl
	    modprobe -q --show nvidia_drm && modprobe nvidia_drm
	    modprobe -q --show nvidia_uvm && modprobe nvidia_uvm
	    modprobe -q --show nvidia_modeset && modprobe nvidia_modeset
	    #modprobe -q --show drm_kms_helper && modprobe drm_kms_helper
	    #modprobe -q --show modprobe drm && modprobe drm
	    #echo -e nvidia_drm\\nvidia_uvm\\nnvidia_modeset > usr/lib/modules-load.d/nvidia-dkms.conf
	fi
        if [[ -d /etc/lightdm ]]; then
            install -Dm644 /dev/stdin ${FILE_LIGHTDM_CONF} <<-EOF
[LightDM]
logind-check-graphical=false
EOF
        fi
    else
	#rm -f "${FILE_TARG_NVIDIA_RULES}"
	rm -f "${FILE_TARG_NVIDIA_CONF}"
	rm -f "${FILE_LIGHTDM_CONF}"
    fi
}

exec_xorg_ext(){
    rm -f /etc/X11/xorg.conf.d/110-xorg-ext-*-ubconfig.conf
## Управление дополнительными возможностями XORG
    if [[ -n ${XORG_EXT} ]]; then
        [[ -d /etc/X11/xorg.conf.d ]] || install -Dm755 /etc/X11/xorg.conf.d
	while read I_EXT; do
	    XORG_FILE_EXT="/etc/X11/xorg.conf.d/110-xorg-ext-${I_EXT}-ubconfig.conf"
	    if [[ ${I_EXT} =~ (^"nodpms"|",nodpms"|";nodpms"|" nodpms") ]]; then
		cat > ${XORG_FILE_EXT} <<EOF
Section "Extensions"
    Option "DPMS" "Disable"
EndSection

Section "ServerFlags"
    Option "StandbyTime" "0"
    Option "SuspendTime" "0"
    Option "OffTime" "0"
    Option "BlankTime" "0"
EndSection
EOF
	    elif [[ ${I_EXT} =~ (^"dpms"|",dpms"|";dpms"|" dpms") ]]; then
		cat > ${XORG_FILE_EXT} <<EOF
Section "Extensions"
    Option "DPMS" "Enable"
EndSection
EOF
	    fi
	done <  <(tr ',' '\n' <<< "${XORG_EXT}")
    fi
}

exec_xorg_monitor(){
## Parametrs:
## cvt | gtf | reduced|r | dpms | nodpms | enable | disable | ignore | primary |
## lo|LeftOf:{name} | ro|RightOf:{name} | ab|Above:{name} | be|Below:{name} |
## rotate:normal | rotate:left | rotate:right | rotate:invert
    XORG_FILE_MONITOR="/etc/X11/xorg.conf.d/120-xorg-monitor-ubconfig.conf"
    rm -f "${XORG_FILE_MONITOR}"
    grep -q xres= /proc/cmdline && XORG_MONITOR=$(cat /proc/cmdline | awk -F xres= '{print $2}' | awk '{print $1}')
    if [[ "${SETXORGRES}" != "no" ]] && [[ -n "${XORG_MONITOR[@]}" ]]; then
        [[ -d /etc/X11/xorg.conf.d ]] || install -Dm755 /etc/X11/xorg.conf.d
	for VIDEO_PORT in "${!XORG_MONITOR[@]}"; do
	    SOFT_MODELINE="gtf"
	    SOFT_MODELINE_R=
	    PREFERRED_MODE=
	    XORG_STR_MONITOR=
	    while read VIDEO_PORT_PARAM; do
		if grep -Eiq "^[0-9]*x[0-9]*$|^[0-9]*x[0-9]*x[0-9]*$" <<< "${VIDEO_PORT_PARAM}"; then
		    if [[ -n ${SOFT_MODELINE_R} ]]; then
			XORG_STR_MONITOR+="$(cvt -r $(sed 's/\([0-9]* [0-9]*\) .*/\1/' <<< ${VIDEO_PORT_PARAM//x/ }))\n"
			SOFT_MODELINE_R=
		    elif [[ ${SOFT_MODELINE} == "cvt" ]]; then
			XORG_STR_MONITOR+="$(cvt ${VIDEO_PORT_PARAM//x/ })\n"
		    else
			if grep -Eiq "^[0-9]*x[0-9]*$" <<< "${VIDEO_PORT_PARAM}"; then
			    XORG_STR_MONITOR+="$(gtf ${VIDEO_PORT_PARAM//x/ } 60 | grep -v '^\s*$')\n"
			else
			    XORG_STR_MONITOR+="$(gtf ${VIDEO_PORT_PARAM//x/ } | grep -v '^\s*$')\n"
			fi
		    fi
		elif grep -Eiq "^cvt$" <<< "${VIDEO_PORT_PARAM}"; then
		    SOFT_MODELINE="cvt"
		elif grep -Eiq "^gtf$" <<< "${VIDEO_PORT_PARAM}"; then
		    SOFT_MODELINE="gtf"
		elif grep -Eiq "^reduced|r$" <<< "${VIDEO_PORT_PARAM}"; then
		    SOFT_MODELINE_R="reduced"
		elif grep -Eiq "^nodpms$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+='  Option "DPMS" "false"\n'
		elif grep -Eiq "^dpms$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+='  Option "DPMS" "true"\n'
		elif grep -Eiq "^enable$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+='  Option "Enable" "true"\n'
		elif grep -Eiq "^disable$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+='  Option "Enable" "false"\n'
		elif grep -Eiq "^ignore$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+='  Option "Ignore" "true"\n'
		elif grep -Eiq "^primary$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+='  Option "Primary" "true"\n'
		elif grep -Eiq "^lo:[[:alnum:]]*$|^LeftOf:[[:alnum:]]*$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+="  Option \"LeftOf\" \"$(cut -d: -f2 <<< ${VIDEO_PORT_PARAM^^})\"\n"
		elif grep -Eiq "^ro:[[:alnum:]]*$|^RightOf:[[:alnum:]]*$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+="  Option \"RightOf\" \"$(cut -d: -f2 <<< ${VIDEO_PORT_PARAM^^})\"\n"
		elif grep -Eiq "^ab:[[:alnum:]]*$|^Above:[[:alnum:]]*$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+="  Option \"Above\" \"$(cut -d: -f2 <<< ${VIDEO_PORT_PARAM^^})\"\n"
		elif grep -Eiq "^be:[[:alnum:]]*$|^Below:[[:alnum:]]*$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+="  Option \"Below\" \"$(cut -d: -f2 <<< ${VIDEO_PORT_PARAM^^})\"\n"
		elif grep -Eiq "^rotate:[[:alpha:]]*$" <<< "${VIDEO_PORT_PARAM}"; then
		    XORG_STR_MONITOR+="  Option \"Rotate\" \"$(cut -d: -f2 <<< ${VIDEO_PORT_PARAM^^})\"\n"
		fi
		[[ -z ${PREFERRED_MODE} ]] && PREFERRED_MODE=$(grep Modeline <<< "${XORG_STR_MONITOR}" | cut -d'"' -f2)
	    done <  <(tr ',' '\n' <<< "${XORG_MONITOR[${VIDEO_PORT}]}")
	    if [[ -n ${XORG_STR_MONITOR} && ${VIDEO_PORT} != 0 ]]; then
	        XORG_STR+='Section "Monitor"\n'
	        XORG_STR+="  Identifier \"${VIDEO_PORT^^}\"\n"
		XORG_STR+="${XORG_STR_MONITOR}"
		[[ -n ${PREFERRED_MODE} ]] && XORG_STR+="  Option \"PreferredMode\" \"${PREFERRED_MODE}\"\n"
		XORG_STR+='EndSection\n\n'
	    fi
	done
	[[ -n ${XORG_STR} ]] && echo -e "${XORG_STR}" > "${XORG_FILE_MONITOR}"
    fi
}

exec_mkkbdfxorg(){
    [[ $(declare -p XKBMODEL 2>/dev/null) =~ "declare -A" ]] || declare -A XKBMODEL
    [[ $(declare -p XKBLAYOUT 2>/dev/null) =~ "declare -A" ]] || declare -A XKBLAYOUT
    [[ $(declare -p XKBVARIANT 2>/dev/null) =~ "declare -A" ]] || declare -A XKBVARIANT
    XORG_FILE_KEYBOARD="/etc/X11/xorg.conf.d/130-mkkbdfxorg-ubconfig.conf"
    XORG_FILE_LOCALECTL="/etc/X11/xorg.conf.d/00-keyboard.conf"
    if [[ ${MKKBDFXORG} =~ @("no"|"disable"|"off") ]]; then
	[[ ! -f ${XORG_FILE_KEYBOARD} ]] || rm -f "${XORG_FILE_KEYBOARD}" 2>/dev/null
    else
	local SET_SECTION= DATA_XORG_FILE_KEYBOARD=
	if [[ -n ${XKBMODEL} ]]; then
	    SET_SECTION+=$'\t'"Option \"XkbModel\" \"${XKBMODEL}\""$'\n'
	elif [[ -n ${XKBMODEL[${LANG%%_*}]} ]]; then
	    SET_SECTION+=$'\t'"Option \"XkbModel\" \"${XKBMODEL[${LANG%%_*}]}\""$'\n'
	    [[ -f ${SYSCONF}/keyboard ]] && sed "/^XKBMODEL=/d" -i "${SYSCONF}/keyboard"
	    echo "XKBMODEL=${XKBMODEL[${LANG%%_*}]}" >> "${SYSCONF}/keyboard"
	fi
	if [[ -n ${XKBLAYOUT} ]]; then
	    SET_SECTION+=$'\t'"Option \"XkbLayout\" \"${XKBLAYOUT}\""$'\n'
	elif [[ -n ${XKBLAYOUT[${LANG%%_*}]} ]]; then
	    SET_SECTION+=$'\t'"Option \"XkbLayout\" \"${XKBLAYOUT[${LANG%%_*}]}\""$'\n'
	    [[ -f ${SYSCONF}/keyboard ]] && sed "/^XKBLAYOUT=/d" -i "${SYSCONF}/keyboard"
	    echo "XKBLAYOUT=${XKBLAYOUT[${LANG%%_*}]}" >> "${SYSCONF}/keyboard"
	fi
	if [[ -n ${XKBVARIANT} ]]; then
	    SET_SECTION+=$'\t'"Option \"XkbVariant\" \"${XKBVARIANT}\""$'\n'
	elif [[ -n ${XKBVARIANT[${LANG%%_*}]} ]]; then
	    SET_SECTION+=$'\t'"Option \"XkbVariant\" \"${XKBVARIANT[${LANG%%_*}]}\""$'\n'
	    [[ -f ${SYSCONF}/keyboard ]] && sed "/^XKBVARIANT=/d" -i "${SYSCONF}/keyboard"
	    echo "XKBVARIANT=${XKBVARIANT[${LANG%%_*}]}" >> "${SYSCONF}/keyboard"
	fi
	if [[ -n ${XKBOPTIONS} ]]; then
	    SET_SECTION+=$'\t'"Option \"XkbOptions\" \"${XKBOPTIONS}\""$'\n'
	fi
	if [[ -n "${XKBMODEL}${XKBLAYOUT}${XKBVARIANT}${XKBOPTIONS}" ]]; then
	    SET_SECTION="\
# Written by /ublinux/rc.post.d/11-xorg, read by manual.
# Use 'ubconfig set [locale] XKBLAYOUT= XKBMODEL= XKBVARIANT= XKBOPTIONS=' to update this file.
Section \"InputClass\"
        Identifier \"system-keyboard\"
        MatchIsKeyboard \"on\"
${SET_SECTION}EndSection
"
	    [[ -f ${XORG_FILE_KEYBOARD} ]] && DATA_XORG_FILE_KEYBOARD=$(< ${XORG_FILE_KEYBOARD})
	    if [[ ! ${DATA_XORG_FILE_KEYBOARD} == ${SET_SECTION} ]]; then
    		[[ -d /etc/X11/xorg.conf.d ]] || install -Dm755 /etc/X11/xorg.conf.d
    		# Если задана раскладка от утилиты localectl, то удалим
    		[[ -f ${XORG_FILE_LOCALECTL} ]] && rm -f "${XORG_FILE_LOCALECTL}" 2>/dev/null
#		if ! grep -sqi XkbOptions /etc/X11/xorg.conf; then
	    	echo -n "${SET_SECTION}" > "${XORG_FILE_KEYBOARD}"
	    fi
	else
	    [[ ! -f ${XORG_FILE_KEYBOARD} ]] || rm -f "${XORG_FILE_KEYBOARD}" 2>/dev/null
	fi
    fi
}

################
##### MAIN #####
################

    # Если файл подключен как ресурс с функциями, то выйти
    return 0 2>/dev/null && return 0
    if [[ -z $@ ]]; then
        while read -r FUNCTION; do
            $"${FUNCTION##* }"
        done < <(declare -F | grep "declare -f exec_")
    else
        FUNCTION=
        while [[ $# -gt 0 ]]; do
            #[[ -z ${1} ]] || { declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1}'"; }
            # Что-бы передавать пустые параметры как аргументы, нужно для соблюдения очередности и кол-ва, отключил [[ -z ${1} ]] ||
            declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1}'"
            shift
        done
        eval ${FUNCTION#*; }
    fi
    true
