#!/usr/bin/env bash

set -uo pipefail

# systemd может не создать $HOME и $USER, берем их из системы
CURRENT_USER=$(id -un)
CURRENT_UID=$(id -u)
home=$(getent passwd "$CURRENT_USER" | cut -d: -f6)
: "${home:=/home/$CURRENT_USER}"

DEBUG_LOG="${home}/.local/share/autosession/debug.log"
[ -f "$DEBUG_LOG" ] && mv "$DEBUG_LOG" "${DEBUG_LOG}_old.log"
mkdir -p "$(dirname "$DEBUG_LOG")"

# Перенаправляем вывод в лог
exec > >(tee -a "$DEBUG_LOG") 2>&1
echo "=== autosession-run started at $(date) ==="

log() { 
    local timestamp
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [autosession] $*" >&2
}

die() { log "ERROR: $*"; exit 1; }

STOP_FLAG="${home}/.cache/autosession-stop"

if [ -e "$STOP_FLAG" ]; then
    log "STOP_FLAG found at $STOP_FLAG — restart disabled. Exiting."
    exit 0
fi

CONF="${AUTOSESSION_CONF:-/etc/autosession.conf}"
[ -r "$CONF" ] || die "Cannot read $CONF"
# shellcheck disable=SC1090
. "$CONF"

[ -n "${1:-}" ] && SESSION_TTY="$1"

: "${SESSION_USER:=live}"
: "${SESSION_TYPE:=auto}"
: "${SESSION:=}"
: "${SESSION_ARGS:=}"
: "${SESSION_TTY:=7}" 
: "${DISPLAY_NUM:=0}"
: "${SESSION_DELAY:=0}"
: "${ENV_FILE:=/etc/autosession.env}"
: "${ON_EXIT:=relogin}"

if [ -r "$ENV_FILE" ]; then
    log "Loading environment from $ENV_FILE"
    set -a
    # shellcheck disable=SC1090
    . "$ENV_FILE"
    set +a
fi

if [ "$SESSION_DELAY" -gt 0 ] 2>/dev/null; then
    log "Waiting ${SESSION_DELAY} seconds..."
    sleep "$SESSION_DELAY"
fi

# Экспорт критического окружения для X11/Wayland/PAM
export XDG_VTNR="$SESSION_TTY"
export XDG_SESSION_CLASS=user
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$CURRENT_UID}"
export DISPLAY=":${DISPLAY_NUM}"
export TERM="${TERM:-linux}"

# Проверяем, существует ли рантайм-директория (важно для Wayland и dbus)
if [ ! -d "$XDG_RUNTIME_DIR" ]; then
    log "WARNING: XDG_RUNTIME_DIR ($XDG_RUNTIME_DIR) does not exist. Creating..."
    # Пытаемся создать, если у пользователя есть права на /run/user
    mkdir -p "$XDG_RUNTIME_DIR" 2>/dev/null && chmod 700 "$XDG_RUNTIME_DIR" 2>/dev/null || true
fi

tty_dev="/dev/tty${SESSION_TTY}"
log "Checking TTY: $tty_dev"
if [ ! -e "$tty_dev" ]; then
    die "TTY $tty_dev does not exist"
fi

# выбор сессии
resolve_session() {
    if [ -z "$SESSION" ]; then
        log "SESSION not specified -> default Xsession"
        CMD_KIND=xsession
        CMD=("/etc/X11/Xsession")
    elif command -v -- "$SESSION" >/dev/null 2>&1; then
        log "SESSION='$SESSION' found in PATH"
        CMD_KIND=executable
        CMD=("$SESSION")
    else
        log "SESSION='$SESSION' not found -> desktop-session"
        CMD_KIND=xsession
        CMD=("/etc/X11/Xsession" "$SESSION")
    fi
}

detect_type() {
    local bin
    bin="$(basename "$1")"
    case "$bin" in
        *wayland|sway*|Hyprland|hyprland*|weston*|wayfire|river|labwc|niri|cage*|\
        miriway|cosmic-comp|gamescope|gnome-session|phosh-session|cosmic-session|swayfx)
            echo wayland ;;
        *)
            echo x11 ;;
    esac
}

resolve_session

if [ "$SESSION_TYPE" = auto ]; then
    if [ "$CMD_KIND" = xsession ]; then
        SESSION_TYPE=x11
    else
        SESSION_TYPE="$(detect_type "${CMD[0]}")"
    fi
    log "SESSION_TYPE=auto -> $SESSION_TYPE"
fi

if [ "$SESSION_TYPE" = x11 ]; then
    command -v xinit >/dev/null 2>&1 || die "xinit not found"
    command -v Xorg >/dev/null 2>&1 || die "Xorg not found"
fi

# Переменная для сохранения кода выхода графического клиента
CLIENT_EXIT=0

# Старт сессии
case "$SESSION_TYPE" in
    wayland)
        log "Starting Wayland session"
        export XDG_SESSION_TYPE=wayland
        
        if ! command -v "${CMD[0]}" >/dev/null 2>&1; then
            die "Wayland compositor ${CMD[0]} not found"
        fi
        
        log "Running: ${CMD[*]} $SESSION_ARGS"
        if command -v dbus-launch >/dev/null 2>&1; then
            dbus-launch --exit-with-session "${CMD[@]}" $SESSION_ARGS
        else
            "${CMD[@]}" $SESSION_ARGS
        fi
        CLIENT_EXIT=$?
        ;;
        
    x11)
        log "Starting X11 session on tty$SESSION_TTY"
        export XDG_SESSION_TYPE=x11
        
        rm -f "$home/.Xauthority" 2>/dev/null || true
        
        if command -v mcookie >/dev/null 2>&1 && command -v xauth >/dev/null 2>&1; then
            log "Generating Xauthority tokens for $DISPLAY..."
            touch "$home/.Xauthority"
            xauth add "${DISPLAY}" . "$(mcookie)" 2>/dev/null || true
        fi
        
        log "Launching Xorg on vt${SESSION_TTY}..."
        /bin/Xorg ":$DISPLAY_NUM" "vt${SESSION_TTY}" -keeptty -novtswitch -sharevts -quiet &
        XORG_PID=$!
        
        log "Waiting for Xorg to become ready..."
        READY=0
        for i in $(seq 1 50); do
            if xset -display "${DISPLAY}" q >/dev/null 2>&1; then
                READY=1
                break
            fi
            sleep 0.1
        done
        
        if [ "$READY" -ne 1 ]; then
            kill "$XORG_PID" 2>/dev/null || true
            die "Xorg failed to start"
        fi
        log "Xorg is ready."
        
        client="$(printf '%q ' "${CMD[@]}")"
        log "Running X client: $client$SESSION_ARGS"
        
        if command -v dbus-launch >/dev/null 2>&1; then
            eval dbus-launch --exit-with-session $client$SESSION_ARGS
        else
            log "WARNING: dbus-launch not found, trying direct run"
            eval $client$SESSION_ARGS
        fi
        CLIENT_EXIT=$?
        
        log "Session finished, stopping Xorg (PID: $XORG_PID)..."
        kill "$XORG_PID" 2>/dev/null || true
        wait $XORG_PID 2>/dev/null || true
        ;;
        
    *)
        die "Unknown SESSION_TYPE='$SESSION_TYPE'"
        ;;
esac

log "Session ended with exit code: $CLIENT_EXIT"

log "Processing ON_EXIT=$ON_EXIT..."

case "$ON_EXIT" in
    relogin)
        log "Action: Relogin requested. Exiting with code 1 for systemd restart."
        exit 1
        ;;
    poweroff)
        log "Action: Poweroff requested."
        loginctl poweroff 2>/dev/null || poweroff 2>/dev/null || shutdown -P now 2>/dev/null || die "Poweroff failed"
        ;;
    reboot)
        log "Action: Reboot requested."
        loginctl reboot 2>/dev/null || reboot 2>/dev/null || shutdown -r now 2>/dev/null || die "Reboot failed"
        ;;
    stop)
        log "Action: Stop requested."
        mkdir -p "$(dirname "$STOP_FLAG")" 2>/dev/null || true
        echo "autosession stop flag" > "$STOP_FLAG" 2>/dev/null || log "WARNING: Cannot create stop flag"
        exit 0
        ;;
    *)
        log "WARNING: Unknown ON_EXIT action '$ON_EXIT'. Defaulting to exit 0."
        exit 0
        ;;
esac
