#!/bin/bash
set -euo pipefail
PATH=/usr/sbin:/usr/bin:/sbin:/bin
export PATH

die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; }
defer() { printf 'INPUT_SETUP_PENDING: %s\n' "$*" >&2; exit 2; }

mode=${1:-}
target=
case "$mode" in
    --system-only) [ "$#" -eq 1 ] || die 'Usage: helink-input-setup --system-only | --user USER' ;;
    --user) [ "$#" -eq 2 ] && [ -n "$2" ] || die 'Usage: helink-input-setup --user USER'; target=$2 ;;
    *) die 'Usage: helink-input-setup --system-only | --user USER' ;;
esac
[ "$(uname -s)" = Linux ] || die 'Only Linux is supported'
[ "$(id -u)" -eq 0 ] || die 'Administrator approval is required'
for command in getent groupadd modprobe udevadm stat; do
    command -v "$command" >/dev/null || die "Missing dependency: $command"
done
if [ -n "$target" ]; then
    [[ "$target" =~ ^[a-zA-Z_][a-zA-Z0-9_.-]*\$?$ ]] || die 'Invalid username'
    account=$(getent passwd "$target") || die 'User does not exist'
    IFS=: read -r username password uid gid gecos home login_shell <<< "$account"
    [ "$username" = "$target" ] && [ "$uid" -gt 0 ] || die 'Refusing to authorize root'
    case "$login_shell" in */nologin|*/false|'') die 'Choose the real desktop user, not a service account' ;; esac
    for command in usermod runuser; do
        command -v "$command" >/dev/null || die "Missing dependency: $command"
    done
    [ -x /usr/bin/helink-input-check ] || die 'Install helink-input-permissions first'
fi

if ! getent group helink-uinput >/dev/null; then
    groupadd --system helink-uinput || getent group helink-uinput >/dev/null || die 'Cannot create helink-uinput group'
fi
group_record=$(getent group helink-uinput) || die 'Cannot resolve helink-uinput group'
IFS=: read -r group_name group_password input_gid group_members <<< "$group_record"
[ "$group_name" = helink-uinput ] && [[ "$input_gid" =~ ^[0-9]+$ ]] && [ "$input_gid" -gt 0 ] || die 'Invalid input group'

if [ -n "$target" ]; then
    configured_groups=$(id -G "$target") || die 'Cannot resolve user groups'
    case " $configured_groups " in
        *" $input_gid "*) printf 'GROUP_UNCHANGED: %s\n' "$target" ;;
        *) usermod -a -G helink-uinput "$target"; printf 'GROUP_ADDED: %s\n' "$target" ;;
    esac
fi

if ! modprobe uinput; then
    [ -c /dev/uinput ] || defer 'Cannot load uinput; persistent policy remains installed. Check kernel support.'
fi
udevadm control --reload-rules || defer 'udev is unavailable; retry in the running target system'
udevadm trigger --action=change --subsystem-match=misc --sysname-match=uinput || defer 'Cannot trigger the uinput device'
udevadm settle --timeout=10 || defer 'udev did not settle; retry setup'
[ -c /dev/uinput ] || defer '/dev/uinput is missing; check kernel support or container device mapping'
device_policy=$(stat -c '%u:%g:%a' /dev/uinput) || defer 'Cannot inspect uinput permissions'
[ "$device_policy" = "0:$input_gid:660" ] || defer 'uinput policy is overridden or not applied; inspect local udev rules. No broad chmod was applied.'

if [ -n "$target" ]; then
    printf 'Checking access in a NEW login context for %s (not the existing desktop process).\n' "$target"
    runuser -u "$target" -- /usr/bin/helink-input-check || defer 'The target user cannot use the uinput driver; see the check result above'
    printf 'EXISTING_SESSION: 保存工作后如有需要请完整注销并重新登录，以让桌面进程及 systemd --user 取得新组。不会强制注销、重启或断开远控。\n'
else
    printf 'SYSTEM_POLICY_OK: uinput policy applied. User authorization is separate; use install-linux.sh or --user DESKTOP_USER.\n'
fi
