#!/usr/bin/env bash
# autosessionctl — управление AutoSession
#
# Использование:
#   autosessionctl enable        enable instead of gdm/sddm/lightdm and start session
#   autosessionctl disable       disable, return console getty
#   autosessionctl status        service and generator status
#   autosessionctl logs          follow logs
#   autosessionctl stop          stop session without restart
#   autosessionctl start         remove stop flag and start session
#   autosessionctl config        show current configuration
#   autosessionctl edit          edit configuration variables
#   autosessionctl restart       restart session
#   autosessionctl cat           show full unit with drop-ins

CONF=/etc/autosession.conf
UNIT=autosession.service
GENERATOR=/usr/lib/systemd/system-generators/autosession-generator

require_root() {
    [ "$(id -u)" -eq 0 ] || { echo "need root: sudo autosessionctl $*" >&2; exit 1; }
}

read_conf() {
    [ -r "$CONF" ] || { echo "error: $CONF not found" >&2; exit 1; }
    # shellcheck disable=SC1090
    . "$CONF"
    : "${SESSION_USER:=live}"
    : "${SESSION_TTY:=7}"
    : "${SESSION:=}"
}

get_stop_flag() {
    local user="${1:-$SESSION_USER}"
    local uid
    uid="$(id -u "$user" 2>/dev/null || echo "1000")"
    if [ -d "/run/user/${uid}" ] && [ -w "/run/user/${uid}" ]; then
        echo "/run/user/${uid}/autosession-stop"
    else
        echo "/home/${user}/.cache/autosession-stop"
    fi
}

case "${1:-help}" in
    enable)
        require_root "$@"
        read_conf

        id "$SESSION_USER" >/dev/null 2>&1 || \
            { echo "error: user $SESSION_USER not found" >&2; exit 1; }

        if [ ! -x "$GENERATOR" ]; then
            echo "warning: generator not found at $GENERATOR"
        fi

        # Если скрипт вызван обычно — мы перезапускаем его же через setsid в фоне
        # Позволит запускать из консолии в сессии с другим DM
        if [ "${AUTOSESSION_BG:-0}" -ne 1 ]; then
            echo "Activating AutoSession... Migrating from current Display Manager."
            export AUTOSESSION_BG=1
            setsid "$0" enable >/dev/null 2>&1 &
           
            echo "Migration worker started in background. Your session will close now."
            exit 0
        fi

        systemctl disable gdm sddm lightdm lxdm nodm mdm tdm kdm xdm 2>/dev/null || true
        systemctl enable "$UNIT" 2>/dev/null || true
        systemctl daemon-reload
        systemctl stop display-manager gdm sddm lightdm lxdm nodm mdm tdm kdm xdm 2>/dev/null || true
        systemctl start "$UNIT"
        
        exit 0
        ;;

    disable)
        require_root "$@"
        systemctl disable --now "$UNIT" 2>/dev/null || true
        systemctl daemon-reload
        echo "AutoSession disabled"
        echo "Do not forget to set up another DM: systemctl enable --now gdm"
        ;;
        
    status)
        echo "=== AutoSession Status ==="
        echo
        echo "--- Service ---"
        systemctl --no-pager -l status "$UNIT" 2>/dev/null || true
        echo
        echo "--- Drop-in (generated) ---"
        ls -lA /run/systemd/generator*/autosession.service.d/ 2>/dev/null || echo "No drop-ins"
        echo
        echo "--- Generator ---"
        if [ -x "$GENERATOR" ]; then
            echo "Generator: $GENERATOR (executable)"
        else
            echo "Generator: $GENERATOR (not found)"
        fi
        ;;
        
    cat)
        require_root "$@"
        echo "=== Full unit with all drop-ins ==="
        echo
        systemctl cat "$UNIT" 2>/dev/null || {
            echo "error: cannot read $UNIT"
            exit 1
        }
        ;;
        
    logs)
        exec journalctl -u "$UNIT" -f
        ;;
        
    stop)
        require_root "$@"
        read_conf
        FLAG="$(get_stop_flag "$SESSION_USER")"
        
        echo "Stopping session for user: $SESSION_USER"
        sudo -u "$SESSION_USER" touch "$FLAG" 2>/dev/null || {
            mkdir -p "$(dirname "$FLAG")" 2>/dev/null || true
            touch "$FLAG" 2>/dev/null || true
        }
        
        systemctl kill -s TERM "$UNIT" 2>/dev/null || true
        echo "Session stopped. Flag: $FLAG"
        echo "Restart: autosessionctl start"
        ;;
        
    start)
        require_root "$@"
        read_conf
        FLAG="$(get_stop_flag "$SESSION_USER")"
        
        sudo -u "$SESSION_USER" rm -f "$FLAG" 2>/dev/null || rm -f "$FLAG" 2>/dev/null || true
        systemctl start "$UNIT"
        echo "Session started."
        ;;

    edit)
        require_root "$@"
        SESSION_USER="live"
        SESSION_TYPE="auto"
        SESSION=""
        SESSION_ARGS=""
        SESSION_TTY="7"
        ON_EXIT="relogin"
        DISPLAY_NUM="0"
        SESSION_DELAY="0"
        ENV_FILE="/etc/autosession.env"

        # Если файл конфигурации существует — накатываем его поверх дефолтов, сохраняя все старые значения
        if [ -r "$CONF" ]; then
            # shellcheck disable=SC1090
            . "$CONF"
        fi

        NEW_USER="${2:-}"
        NEW_SCRIPT="${3:-}"
        NEW_TTY="${4:-}"

        if [ -z "$NEW_USER" ] && [ -z "$NEW_SCRIPT" ] && [ -z "$NEW_TTY" ]; then
            echo "=== AutoSession Configuration Editor ==="
            echo "Press ENTER to keep current value or '-' to clear."
            echo
            read -r -p "Username [$SESSION_USER]: " input; [ -n "$input" ] && NEW_USER="$input"
            read -r -p "Start script/session [$SESSION]: " input; [ -n "$input" ] && NEW_SCRIPT="$input"
            read -r -p "TTY number [$SESSION_TTY]: " input; [ -n "$input" ] && NEW_TTY="$input"
        fi

        # Обработка пропусков: если аргумент пуст или равен '-', оставляем то, что было в конфиге
        [ -z "$NEW_USER" ] || [ "$NEW_USER" = "-" ] && NEW_USER="$SESSION_USER"
        [ -z "$NEW_SCRIPT" ] || [ "$NEW_SCRIPT" = "-" ] && NEW_SCRIPT="$SESSION"
        [ -z "$NEW_TTY" ] || [ "$NEW_TTY" = "-" ] && NEW_TTY="$SESSION_TTY"

        # Если TTY остался пустым (не задан ни в аргументах, ни в самом конфиге), ставим дефолт 7
        [ -z "$NEW_TTY" ] && NEW_TTY="7"

        # Валидация измененных критических параметров
        id "$NEW_USER" >/dev/null 2>&1 || { echo "error: user '$NEW_USER' does not exist" >&2; exit 1; }
        [[ "$NEW_TTY" =~ ^[0-9]+$ ]] || { echo "error: TTY must be a number (e.g., 7)" >&2; exit 1; }


        # Создаем родительскую директорию, если конфига никогда не было
        mkdir -p "$(dirname "$CONF")"

        # Атомарная запись: сохраняем структуру, комментарии и абсолютно все переменные
        TMP_CONF=$(mktemp /etc/autosession.conf.XXXXXX)
        cat <<EOF > "$TMP_CONF"
# ────────────────────────────────────────────────────────────────
#  /etc/autosession.conf
#  Docs: /usr/share/doc/autosession/README.md
#  Reload: systemctl daemon-reload ; systemctl restart autosession
#  Generated via 'autosessionctl edit'
# ────────────────────────────────────────────────────────────────

# User | Пользователь (live)
SESSION_USER="${NEW_USER}"

# Type | Тип: auto | wayland | x11 (auto)
SESSION_TYPE="${SESSION_TYPE}"

# Session command | Команда сессии (PATH or .desktop)
SESSION="${NEW_SCRIPT}"

# Session args | Аргументы сессии
SESSION_ARGS="${SESSION_ARGS}"

# TTY number | Номер tty (7)
SESSION_TTY="${NEW_TTY}"

# On exit | Действие: relogin | stop | reboot | poweroff (relogin)
ON_EXIT="${ON_EXIT}"

# X display number | Номер X-дисплея (:0)
DISPLAY_NUM="${DISPLAY_NUM}"

# Startup delay (sec) | Задержка старта (сек) (0)
SESSION_DELAY="${SESSION_DELAY}"

# Extra env file | Файл с переменными окружения (/etc/autosession.env)
ENV_FILE="${ENV_FILE}"
EOF
        
        chmod 644 "$TMP_CONF"
        mv "$TMP_CONF" "$CONF"

        echo "Configuration updated successfully in $CONF"
        
        # Перезапускаем генераторы сразу, чтобы применить структуру TTY/User
        echo "Reloading systemd daemon..."
        systemctl daemon-reload
        echo
        echo "=== Next Steps ==="
        echo "To apply changes and INSTANTLY restart your active AutoSession, run:"
        echo "  sudo autosessionctl restart"
        echo
        echo "To INSTANTLY replace your current DM and launch AutoSession right now, run:"
        echo "  sudo autosessionctl enable"
        echo
        ;;

    restart)
        require_root "$@"
        systemctl restart "$UNIT"
        echo "Session restarted."
        ;;
        
    config)
        read_conf
        echo "=== AutoSession Configuration ==="
        echo "Config: $CONF"
        echo
        cat "$CONF"
        echo
        echo "--- Runtime ---"
        echo "Stop flag: $(get_stop_flag "$SESSION_USER")"
        echo "User: $SESSION_USER"
        ;;
        
    help|*)
        sed -n '2,11p' "$0" | sed 's/^# \{0,1\}//'
        echo
        echo "Commands: enable | disable | status | logs | edit |"
        echo "          stop | start | restart | config | cat"
        ;;
esac

