#!/bin/bash
# chksession - Session selector for X11/Wayland sessions

set -e

# Function: check if command exists and is executable
is_executable() {
    local cmd="${1%% *}"
    [[ -n "$cmd" ]] && command -v "$cmd" >/dev/null 2>&1
}

# Function: parse desktop file and extract Name and Exec
parse_desktop() {
    local file="$1"
    local name=""
    local exec_cmd=""
    
    name=$(grep -m1 '^Name=' "$file" | cut -d= -f2-)
    exec_cmd=$(grep -m1 '^Exec=' "$file" | cut -d= -f2-)
    
    if [[ -n "$name" && -n "$exec_cmd" ]]; then
        echo "$name|||$exec_cmd"
        return 0
    fi
    return 1
}

# Function: find first valid session name in directory
find_first_session_name() {
    local dir="$1"
    
    [[ -d "$dir" ]] || return 1
    
    for f in "$dir"/*.desktop; do
        [[ -f "$f" ]] || continue
        
        case "$f" in
            *~|*.rpmnew|*.rpmsave) continue ;;
        esac
        
        parsed=$(parse_desktop "$f" 2>/dev/null) || continue
        
        name="${parsed%%|||*}"
        exec_cmd="${parsed#*|||}"
        
        if is_executable "$exec_cmd"; then
            echo "$name"
            return 0
        fi
    done
    
    return 1
}

# Function: find session by name (exact or partial match, case-insensitive)
find_session_by_name() {
    local search_name="$1"
    local search_lower=$(echo "$search_name" | tr '[:upper:]' '[:lower:]')
    
    for dir in "/usr/share/xsessions" "/usr/share/wayland-sessions"; do
        [[ -d "$dir" ]] || continue
        
        for f in "$dir"/*.desktop; do
            [[ -f "$f" ]] || continue
            
            case "$f" in
                *~|*.rpmnew|*.rpmsave) continue ;;
            esac
            
            parsed=$(parse_desktop "$f" 2>/dev/null) || continue
            
            name="${parsed%%|||*}"
            exec_cmd="${parsed#*|||}"
            
            name_lower=$(echo "$name" | tr '[:upper:]' '[:lower:]')
            
            # Exact match (case-insensitive)
            if [[ "$name_lower" == "$search_lower" ]] && is_executable "$exec_cmd"; then
                echo "$exec_cmd"
                return 0
            fi
            
            # Partial match by first word (case-insensitive)
            first_word="${name%%[ (]*}"
            first_word_lower=$(echo "$first_word" | tr '[:upper:]' '[:lower:]')
            if [[ "$first_word_lower" == "$search_lower" ]] && is_executable "$exec_cmd"; then
                echo "$exec_cmd"
                return 0
            fi
        done
    done
    
    return 1
}

# Parse arguments
first=false
xsession=""

for arg in "$@"; do
    case "$arg" in
        -F|--first)
            first=true
            ;;
        -x=*|--xsession=*)
            if [[ "$arg" =~ ^-x=(.*)$ ]]; then
                xsession="${BASH_REMATCH[1]}"
            elif [[ "$arg" =~ ^--xsession=(.*)$ ]]; then
                xsession="${BASH_REMATCH[1]}"
            fi
            ;;
        -h|--help|-?)
            cat <<EOF
Usage: ${0##*/} [OPTION]

-F, --first              Print first available session name (X11 preferred)
-x=ENTRY, --xsession=ENTRY  Print Exec command for session (case-insensitive, partial match by first word)
-h, --help               This help
EOF
            exit 0
            ;;
        *)
            echo "Unrecognized option: $arg" >&2
            exit 0 # original script has more args, just return zero
            ;;
    esac
done

if $first; then
    name=$(find_first_session_name "/usr/share/xsessions") || \
        name=$(find_first_session_name "/usr/share/wayland-sessions")
    
    if [[ -n "$name" ]]; then
        echo "$name"
    else
        echo "default"
    fi
    exit 0
fi

if [[ -n "$xsession" ]]; then
    exec_cmd=$(find_session_by_name "$xsession")
    
    if [[ -n "$exec_cmd" ]]; then
        echo "$exec_cmd"
        exit 0
    fi
    
    if is_executable "xdg-terminal"; then
        echo "xdg-terminal"
        exit 0
    elif is_executable "xterm"; then
        echo "xterm"
        exit 0
    else
        echo "default"
        exit 0
    fi
fi

exit 0
