# This file is part of LTSP, https://ltsp.org
# Copyright 2019-2022 the LTSP team, see AUTHORS
# SPDX-License-Identifier: GPL-3.0-or-later

# Handle tasks related to display managers.
# Patching arbitrary .conf files is hard; let's try appending the sections
# we want to the existing files and hope this properly overrides
# @LTSP.CONF: AUTOLOGIN RELOGIN GDM3_CONF LIGHTDM_CONF SDDM_CONF SLICK_CONF
# @LTSP.CONF: LTSPDM_USERS

display_manager_main() {
    local _ALUSER _AUTOLOGIN _RELOGIN

    if [ -z "$AUTOLOGIN" ]; then
        _ALUSER=
    elif ! _ALUSER=$(echo "$HOSTNAME" | sed "s/$AUTOLOGIN/" 2>/dev/null); then
        # AUTOLOGIN can either be a valid sed regex or a username
        _ALUSER=$AUTOLOGIN
    fi
    # Ignore non-existing users as e.g. lightdm displays artifacts
    if [ -n "$_ALUSER" ] && ! getent passwd "$_ALUSER" >/dev/null; then
        _ALUSER=
    fi
    if [ -n "$_ALUSER" ]; then
        _AUTOLOGIN=true
    else
        _AUTOLOGIN=false
    fi
    if [ "$RELOGIN" = "0" ]; then
        _RELOGIN=false
    else
        _RELOGIN=true
    fi
    re configure_gdm
    re configure_lightdm
    re configure_sddm
    re ltspdm
}

configure_gdm() {
    local conf

    is_command gdm3 || return 0
    re mkdir -p /etc/gdm3
    # Some distributions used daemon.conf instead of upstream custom.conf?
    if [ -f /etc/gdm3/daemon.conf ]; then
        conf=/etc/gdm3/daemon.conf
    else
        conf=/etc/gdm3/custom.conf
    fi
    {
        echo "
# Generated by \`ltsp init\`, see man:ltsp(8)
# You can append content here by specifying the GDM3_CONF parameter
[daemon]
AutomaticLoginEnable=$_AUTOLOGIN
AutomaticLogin=$_ALUSER"
        if [ -f "$GDM3_CONF" ]; then
            re cat "$GDM3_CONF"
        elif [ -n "$GDM3_CONF" ]; then
            echo "$GDM3_CONF"
        fi
    } >>"$conf"
}

configure_lightdm() {
    local timeout

    is_command lightdm || return 0
    # Work around https://github.com/canonical/lightdm/issues/97
    if [ "$RELOGIN" = "0" ]; then
        timeout=${RELOGIN_TIMEOUT:-0}
    else
        timeout=${RELOGIN_TIMEOUT:-2}
    fi
    re mkdir -p /etc/lightdm
    {
        echo "
# Generated by \`ltsp init\`, see man:ltsp(8)
# You can append content here by specifying the LIGHTDM_CONF parameter
[Seat:*]
# Work around https://github.com/CanonicalLtd/lightdm/issues/49
greeter-show-manual-login=true
greeter-hide-users=false
autologin-user=$_ALUSER
autologin-user-timeout=$timeout"
        if [ -f "$LIGHTDM_CONF" ]; then
            re cat "$LIGHTDM_CONF"
        elif [ -n "$LIGHTDM_CONF" ]; then
            echo "$LIGHTDM_CONF"
        fi
    } >>/etc/lightdm/lightdm.conf
}

configure_sddm() {
    is_command sddm || return 0
    # Defining a session is required for autologin to work in sddm
    for session in /usr/share/xsessions/plasma.desktop \
        /usr/share/xsessions/*.desktop; do
        test -f "$session" && break
    done
    if [ -f "$session" ]; then
        session=${session#/usr/share/xsessions/}
    else
        session=
    fi
    {
        echo "
# Generated by \`ltsp init\`, see man:ltsp(8)
# You can append content here by specifying the SDDM_CONF parameter
[Autologin]
User=$_ALUSER
Session=$session
Relogin=$_RELOGIN"
        if [ -f "$SDDM_CONF" ]; then
            re cat "$SDDM_CONF"
        elif [ -n "$SDDM_CONF" ]; then
            echo "$SDDM_CONF"
        fi
    } >>/etc/sddm.conf
}

# Create a system group called ltspdm. Add some users that match a regex
# there. Touch accountsservice info for these users, delete info for all
# other users, and try to configure the DM to display only these users.
ltspdm() {
    local dmregex dmusers user

    test -n "$LTSPDM_USERS" || return 0

    dmregex=$(re eval_percent "$LTSPDM_USERS")
    dmusers=$(re getent passwd |
        re awk -F: '$1 ~ "^'"$dmregex"'$" { print $1 }')
    if [ -z "$dmusers" ]; then
        warn "No users matched LTSPDM_USERS=$dmregex"
        return 0
    fi
    if [ -d /var/lib/AccountsService/users ]; then
        # Some DMs list (or sort) users that have accountsservice information
        # Delete information for all undefined users
        for user in /var/lib/AccountsService/users/*; do
            test -f "$user" || continue
            user=${user#/var/lib/AccountsService/users/}
            case "$_NL$dmusers$_NL" in
            *"$_NL$user$_NL"*) ;;
            *) re rm -f "/var/lib/AccountsService/users/$user" ;;
            esac
        done
        # And touch/create information for all defined users
        for user in $dmusers; do
            re touch "/var/lib/AccountsService/users/$user"
        done
    fi
    # Derivatives of unity-greeter support showing only the members of a group
    # Create an ltspdm group if it doesn't exist
    if ! getent group ltspdm 2>/dev/null; then
        re groupadd --system ltspdm
    fi
    # Set the group members; this doesn't keep any existing ones
    re gpasswd -M "$(printf "%s" "$dmusers" | tr "$_NL" ",")" ltspdm
    # Create the appropriate slick-greeter configuration
    if is_command slick-greeter; then
        {
            echo "
# Generated by \`ltsp init\`, see man:ltsp(8)
# You can append content here by specifying the SLICK_CONF parameter
[Greeter]
group-filter=ltspdm"
            if [ -f "$SLICK_CONF" ]; then
                re cat "$SLICK_CONF"
            elif [ -n "$SLICK_CONF" ]; then
                echo "$SLICK_CONF"
            fi
        } >>/etc/lightdm/slick-greeter.conf
    fi
    # Inject a dconf key for arctica-greeter as it doesn't support conffiles
    if is_command arctica-greeter &&
        [ -f /usr/lib/lightdm/lightdm-greeter-session ]; then
        sed "s|^exec|dconf write /org/ArcticaProject/arctica-greeter/group-filter \"['ltspdm']\"\nexec|" \
            -i /usr/lib/lightdm/lightdm-greeter-session
    fi
}
