#! /bin/bash

args=$1
xephyr_display=5
user_info_flag=false
xephyr_pointer_devID=''
xephyr_pointer_devName=''
xephyr_keyboard_devID=''
xephyr_keyboard_devName=''
xephyr_touch_devID=''
xephyr_touch_devName=''
xephyr_output_name=''
vga_pos=''
config_file="/home/$USER/.config/xephyrConfig"
tmp_config_file="/tmp/xephyrConfig"
control_output_file="/home/$USER/.config/ukui-control-center-security-config.json"
ctuser_session_log_file="/tmp/xephyr_ctuser_session.log"
ctuser_session_wrapper="/tmp/xephyr-ctuser-session.sh"
use_double_input=
RED='\e[31m'
GREEN='\e[32m'
RESET='\e[0m'
xephyr_user='CTUSER'
xephyr_home="/home/$xephyr_user"
ctuser_runtime_dir="/tmp/runtime-$xephyr_user"
xephyr_passwd=

ac_comp_time="-1"         # sleep-computer-ac
battery_comp_time="-1"    # sleep-computer-battery
ac_disp_time="-1"         # sleep-display-ac
battery_disp_time="-1"    # sleep-display-battery
idle_lock_time="-1"       # idle-lock
idle_delay_time="-1"      # idle-delay


# 定义用于匹配触摸设备名称的正则表达式：
# - [Tt][Oo][Uu][Cc][Hh] 匹配任意大小写组合的 "touch"
# - TP 精确匹配大写的 "TP"
TOUCH_REGEX='[Tt][Oo][Uu][Cc][Hh]|TP'

PRIMARY_PORT_PATTERN='VGA|DisplayPort'

log_time() {
    local line_no="${BASH_LINENO[0]}"
    echo "[$(date '+%F %T')] [line:${line_no}] $*"
}

if [ "$(whoami)" = "root" ]; then
    echo "请使用普通用户部署环境，无需root权限"
    exit
fi

if [ -z "$args" ] || [ "$args" == "new" ]; then
    result=$(dbus-send --session --type=method_call --print-reply --dest=org.ukui.KWin /KWin org.ukui.KWin.isExistXephyr)
    boolean_value=$(echo "$result" | awk '/boolean/ {print $NF}')
    if [ "x$boolean_value" = "xtrue" ];then
        echo '隔离环境已启动，无需再次启动'
        exit
    fi

    output_count=$(xrandr --listmonitors |grep Monitors | sed 's/.*\([^ ]\)$/\1/')
    if [ "$output_count" -lt 2 ]; then
        echo "当前为单一显示器，请使用双屏显示"
        exit
    fi

    if pgrep kylin-xephyr > /dev/null;then
        result=$(dbus-send --session --type=method_call --print-reply --dest=com.kylin.Xephyr /Xephyr com.kylin.Xephyr.doubleInput)
        use_double_input=$(echo "$result" | awk '/boolean/ {print $NF}')
        if [ "$use_double_input" = "true" ];then
            echo "副屏使用键鼠，正在检查键鼠数量"
        else
            echo "副屏不使用键盘鼠标，仅使用触摸屏操作"
        fi
    fi

    if [ -z "$use_double_input" ];then
        read -p "启动终端工作空间时，副屏为普通显示器，需配合独立键鼠使用。请确认? (y/n): " choice

        case "$choice" in
            y|Y )
                echo "副屏为普通显示器，使用键鼠，正在检查键鼠数量"
                use_double_input=true
                ;;
            n|N )
                echo "副屏为触摸屏，不使用键盘鼠标，请使用触摸屏操作"
                use_double_input=false
                ;;
            * )
                echo "无效选择，请输入 y 或 n。"
                exit
                ;;
        esac
    fi

fi

check_user_info() {
    #log_time "check_user_info: start"
    echo -e "${GREEN}副屏用户 : CTUSER${RESET}"
    if ! id "$xephyr_user" >/dev/null 2>&1; then
        echo "使用隔离环境的用户不存在"
        exit
    fi
    xephyr_home=$(getent passwd "$xephyr_user" | awk -F: '{print $6}')
    [ -z "$xephyr_home" ] && xephyr_home="/home/$xephyr_user"
    ctuser_runtime_dir="/tmp/runtime-$xephyr_user"

    if pgrep kylin-xephyr > /dev/null;then
        result=$(dbus-send --session --type=method_call --print-reply --dest=com.kylin.Xephyr /Xephyr com.kylin.Xephyr.xephyrPasswd)
        xephyr_passwd=$(echo "$result" | awk '/string/ {print $NF}' | tr -d '"')
    else
        read -sp "请输入使用隔离环境用户的密码:"  xephyr_passwd
    fi

    if [ -n "$xephyr_passwd" ]; then
        echo "$xephyr_passwd" | su "$xephyr_user" > /dev/null 2>&1
        if [ $? -ne 0 ];then
            #log_time "check_user_info: password verification failed"
            echo -e "密码输入错误,请确认"
            read_device_id
            clean_xephyr
            exit
        else
            #log_time "check_user_info: password verification passed"
            echo -e "\n部署隔离环境中,请稍后..."
        fi
    else
        echo -e "\n输入密码为空"
        exit
    fi
    cat <<EOF >> $config_file
user:$xephyr_user
passwd:$xephyr_passwd
EOF
    user_info_flag=true
    #log_time "check_user_info: end"
}

check_ctuser_home() {
    if [ ! -d "$xephyr_home" ]; then
        echo "副屏用户家目录不存在: $xephyr_home"
        exit
    fi

    home_owner=$(stat -c '%U' "$xephyr_home" 2>/dev/null)
    home_group=$(stat -c '%G' "$xephyr_home" 2>/dev/null)

    if [ "$home_owner" != "$xephyr_user" ] || [ "$home_group" != "$xephyr_user" ]; then
        echo "副屏用户家目录属主异常: $xephyr_home 当前为 $home_owner:$home_group，期望为 $xephyr_user:$xephyr_user"
        echo "请先执行 sudo chown -R $xephyr_user:$xephyr_user $xephyr_home 后再重试"
        exit
    fi

    if ! echo "$xephyr_passwd" | su - "$xephyr_user" -c "test -w '$xephyr_home'" > /dev/null 2>&1; then
        echo "副屏用户家目录不可写: $xephyr_home"
        exit
    fi

    # 预创建 CTUSER 用户的配置目录（不包含运行时目录）
    if ! echo "$xephyr_passwd" | su - "$xephyr_user" -c "mkdir -p '$ctuser_runtime_dir' && chown $xephyr_user:$xephyr_user '$ctuser_runtime_dir' && chmod 700 '$ctuser_runtime_dir'" > /dev/null 2>&1; then
        echo "副屏用户运行目录创建/修复失败，请检查 $xephyr_home 权限"
        exit
    fi
}

clean_xephyr() {
    killall Xephyr 2>/dev/null &

    reattach_device() {
        local deviceID=$1
        local deviceType=$2
        if [ -n "$deviceID" ]; then
            xinput reattach "$deviceID" "$deviceType"
        fi
    }

    reattach_device "$xephyr_pointer_devID" "Virtual core pointer"
    reattach_device "$xephyr_keyboard_devID" "Virtual core keyboard"
    reattach_device "$xephyr_touch_devID" "Virtual core pointer"

    if xinput | grep -q "xephyr pointer"; then
        xinput remove-master "xephyr pointer"
    fi

    if [ -f $config_file ];then
        xephyr_user=$(cat $config_file | grep user | awk -F: '{print $2}')
        xephyr_passwd=$(cat $config_file | grep passwd | awk -F: '{print $2}')
    fi
    echo "$xephyr_passwd" | su - "$xephyr_user" -c "pkill -u $xephyr_user" > /dev/null 2>&1 &

    power_states "enable"

    [ -f "$control_output_file" ] && rm "$control_output_file"
    [ -f $config_file ] && rm $config_file

    if pgrep kylin-xephyr > /dev/null;then
        result=$(dbus-send --session --type=method_call --print-reply --dest=com.kylin.Xephyr /Xephyr com.kylin.Xephyr.xephyrPasswd)
        xephyr_passwd=$(echo "$result" | awk '/string/ {print $NF}' | tr -d '"')
        echo "$xephyr_passwd" | su - "$xephyr_user" -c "pkill -u $xephyr_user" > /dev/null 2>&1 &
    fi

}

reattach_touch_device() {
    if [ -n "$xephyr_touch_devID" ] && [ -n "$xephyr_touch_devName" ] ;then
        echo -e "${RED}副屏用户环境的触摸设备$xephyr_touch_devID：$xephyr_touch_devName${RESET}"
        xinput reattach $xephyr_touch_devID "xephyr pointer"
    fi
}

reattach_input_device() {
    if [ -n "$xephyr_pointer_devID" ] && [ -n "$xephyr_pointer_devName" ] ;then
        xinput reattach $xephyr_pointer_devID "xephyr pointer"
    fi

    if [ -n "$xephyr_keyboard_devID" ] && [ -n "$xephyr_keyboard_devName" ] ;then
        xinput reattach $xephyr_keyboard_devID "xephyr keyboard"
    fi
}

get_power_states() {
    ac_comp_time=$(gsettings get org.ukui.power-manager sleep-computer-ac)
    battery_comp_time=$(gsettings get org.ukui.power-manager sleep-computer-battery)
    ac_disp_time=$(gsettings get org.ukui.power-manager sleep-display-ac)
    battery_disp_time=$(gsettings get org.ukui.power-manager sleep-display-battery)

    idle_delay_time=$(gsettings get org.ukui.screensaver idle-delay)
    idle_lock_time=$(gsettings get org.ukui.screensaver idle-lock)

    cat <<EOF >> "$config_file"
ac_comp_time:$ac_comp_time
battery_comp_time:$battery_comp_time
ac_disp_time:$ac_disp_time
battery_disp_time:$battery_disp_time
idle_delay_time:$idle_delay_time
idle_lock_time:$idle_lock_time
EOF
}

load_power_states_from_file() {
    ac_comp_time=$(grep '^ac_comp_time:' "$config_file" | awk -F: '{print $2}' | tr -d ' ')
    battery_comp_time=$(grep '^battery_comp_time:' "$config_file" | awk -F: '{print $2}' | tr -d ' ')
    ac_disp_time=$(grep '^ac_disp_time:' "$config_file" | awk -F: '{print $2}' | tr -d ' ')
    battery_disp_time=$(grep '^battery_disp_time:' "$config_file" | awk -F: '{print $2}' | tr -d ' ')
    idle_delay_time=$(grep '^idle_delay_time:' "$config_file" | awk -F: '{print $2}' | tr -d ' ')
    idle_lock_time=$(grep '^idle_lock_time:' "$config_file" | awk -F: '{print $2}' | tr -d ' ')

    # 如果为空则赋默认值 -1
    [ -z "$ac_comp_time" ] && ac_comp_time="-1"
    [ -z "$battery_comp_time" ] && battery_comp_time="-1"
    [ -z "$ac_disp_time" ] && ac_disp_time="-1"
    [ -z "$battery_disp_time" ] && battery_disp_time="-1"
    [ -z "$idle_delay_time" ] && idle_delay_time="-1"
    [ -z "$idle_lock_time" ] && idle_lock_time="-1"
}

power_states() {
    states=$1
    #log_time "power_states: start states=$states"
    if [ "$states" = "disable" ]; then
        get_power_states
        time="-1"
        gsettings set org.ukui.power-manager sleep-computer-ac "$time"
        gsettings set org.ukui.power-manager sleep-computer-battery "$time"
        gsettings set org.ukui.power-manager sleep-display-ac "$time"
        gsettings set org.ukui.power-manager sleep-display-battery "$time"
        gsettings set org.ukui.screensaver idle-delay "$time"
        gsettings set org.ukui.screensaver idle-lock "$time"
    elif [ "$states" = "enable" ]; then
        load_power_states_from_file
        gsettings set org.ukui.power-manager sleep-computer-ac "$ac_comp_time"
        gsettings set org.ukui.power-manager sleep-computer-battery "$battery_comp_time"
        gsettings set org.ukui.power-manager sleep-display-ac "$ac_disp_time"
        gsettings set org.ukui.power-manager sleep-display-battery "$battery_disp_time"
        gsettings set org.ukui.screensaver idle-delay "$idle_delay_time"
        gsettings set org.ukui.screensaver idle-lock "$idle_lock_time"
    fi
    #log_time "power_states: end states=$states"
}

xephyr_start() {
    #log_time "xephyr_start: start useDoubleInput=$use_double_input output=$xephyr_output_name display=:$xephyr_display"

    # 确保运行时目录存在并设置正确权限（XDG_RUNTIME_DIR）
    mkdir -p "$ctuser_runtime_dir"
    chown "$xephyr_user:$xephyr_user" "$ctuser_runtime_dir" 2>/dev/null || true
    #log_time "xephyr_start: ensured runtime dir $ctuser_runtime_dir"

    # 验证运行时目录的可访问性（以 CTUSER 身份验证）
    if ! echo "$xephyr_passwd" | su - "$xephyr_user" -c "test -d '$ctuser_runtime_dir' && test -w '$ctuser_runtime_dir'" > /dev/null 2>&1; then
        echo "错误：无法以 $xephyr_user 身份访问运行时目录 $ctuser_runtime_dir"
        exit
    fi

    : > "$ctuser_session_log_file"
    chmod 666 "$ctuser_session_log_file"

    if [ "$use_double_input" = "true" ];then
	    Xephyr :"$xephyr_display" -br -ac  -noreset -output $xephyr_output_name 2>/dev/null &
    else
        Xephyr :"$xephyr_display" -br -ac  -touch -nocursor -noreset -output $xephyr_output_name 2>/dev/null &
    fi
    xephyr_pid=$!
    #log_time "xephyr_start: Xephyr launch command dispatched pid=$xephyr_pid"

    if [ "$use_double_input" = "false" ];then
        touch_device_map
    fi

    cat > "$ctuser_session_wrapper" << EOF
#! /bin/sh
(
    sleep 5
    gsettings set org.ukui.power-manager sleep-computer-ac -1
    gsettings set org.ukui.power-manager sleep-computer-battery -1
    gsettings set org.ukui.power-manager sleep-display-ac -1
    gsettings set org.ukui.power-manager sleep-display-battery -1
    gsettings set org.ukui.screensaver idle-delay -1
    gsettings set org.ukui.screensaver idle-lock -1
) >> "$ctuser_session_log_file" 2>&1 &
exec /usr/bin/ukui-session
EOF
    chmod 755 "$ctuser_session_wrapper"

    echo "$xephyr_passwd" | su - "$xephyr_user" -c "sh -lc 'log_file=\"$ctuser_session_log_file\"; echo \"[\$(date \"+%F %T\")] ctuser_session: start DISPLAY=:$xephyr_display XDG_RUNTIME_DIR=$ctuser_runtime_dir\" >> \"\$log_file\"; SESSION_START=xephyr XDG_SESSION_TYPE=x11 XDG_SESSION_DESKTOP=ukui XDG_RUNTIME_DIR=$ctuser_runtime_dir DISPLAY=:$xephyr_display lightdm-session \"$ctuser_session_wrapper\" >> \"\$log_file\" 2>&1; status=\$?; echo \"[\$(date \"+%F %T\")] ctuser_session: end status=\$status\" >> \"\$log_file\"; exit \$status'" > /dev/null 2>&1 &
    ctuser_session_pid=$!
    #log_time "xephyr_start: CTUSER lightdm-session launch command dispatched pid=$ctuser_session_pid"

    cat > $control_output_file << EOF
{
    "Name": "org.ukui.ukcc.session",
    "Path": "/",
    "Interfaces": "org.ukui.ukcc.session.interface",
    "ukcc": [
        {
            "childnode": [
                {
                    "name": "display",
                    "visible": true,
                    "displaySettings": "nightModeFrame:true,brightnessFrame:true",
                    "displayEnable": "displayAllPage:true,mMultiScreenFrame:false,mScreenFrame:false,mResolution:false,mRotation:false,mRefreshRate:false,scaleFrame:false,showMonitorframe:false,showMonitorframe:false,BrightnessFrameV:true,mEyesModeFrame:true,mOpenFrame:true,mTimeModeFrame:true,mCustomTimeFrame:true,mTemptFrame:true,QMLOutputFrame:false"
                }
            ],
            "name": "system",
            "visible": true
        }
    ]
}
EOF

    echo "$xephyr_passwd" | su - "$xephyr_user" -c  "
cat > '$xephyr_home/.config/ukui-control-center-security-config.json' << EOF
{
    \"Name\": \"org.ukui.ukcc.session\",
    \"Path\": \"/\",
    \"Interfaces\": \"org.ukui.ukcc.session.interface\",
    \"ukcc\": [
        {
            \"childnode\": [
                {
                    \"name\": \"display\",
                    \"visible\": true,
                    \"displaySettings\": \"nightModeFrame:true,brightnessFrame:true\",
                    \"displayEnable\": \"displayAllPage:true,mMultiScreenFrame:false,mScreenFrame:false,mResolution:false,mRotation:false,mRefreshRate:false,scaleFrame:false,showMonitorframe:false,showMonitorframe:false,BrightnessFrameV:false,mEyesModeFrame:false,mOpenFrame:false,mTimeModeFrame:false,mCustomTimeFrame:false,mTemptFrame:false,QMLOutputFrame:false\"
                }
            ],
            \"name\": \"system\",
            \"visible\": true
        }
    ]
}
EOF
" > /dev/null 2>&1 &
    power_states "disable"

    if [ "$use_double_input" = "false" ]; then
        sleep 6
        update_touch_id
        read_device_id
        [ -n "$xephyr_touch_devID" ] && xinput reattach "$xephyr_touch_devID" "xephyr pointer"
        touch_device_map
        cp $config_file $tmp_config_file
    fi
    #log_time "xephyr_start: end"
}

touch_device_map() {
    if [ ! $xephyr_output_name ]; then
        xephyr_output_name=$(cat $config_file | grep output | awk -F: '{print $2}')
    fi

    if [ -n "$xephyr_touch_devID" ] && [ -n "$xephyr_output_name" ] ;then
        xinput map-to-output $xephyr_touch_devID $xephyr_output_name
    else
        echo -e "xephyr_output_name: $xephyr_output_name"
        echo -e "xephyr_touch_devID: $xephyr_touch_devID"
        echo -e "${GREEN}未检测到触摸设备，请重新插拔，清理部署，再重新开始部署${RESET}"
        exit
    fi
    echo -e "xephyr_output_name: $xephyr_output_name"
    echo -e "xephyr_touch_devID: $xephyr_touch_devID"
}

extract_geometry() {
    local grep_pattern=$1
    local geometry_info=""

    while read -r line; do
        name=$(echo "$line" | awk -F 'Output: ' '{print $2}' | awk '{print $2}' | sed 's/\x1b\[[0-9;]*m//g')
        mode=$(echo "$line" | sed 's/\x1b\[[0-9;]*m//g' | grep -oP '\d+:1920x1080' | head -n 1 | cut -d: -f1)
        pos=$(echo "$line" | awk -F 'Geometry: ' '{print $2}' | awk '{print $1}' | sed 's/\x1b\[[0-9;]*m//g')
        geometry=$(echo "$line" | awk -F 'Geometry: ' '{print $2}' | awk '{print $2}' | sed 's/\x1b\[[0-9;]*m//g')
        rotation=$(echo "$line" | awk -F 'Geometry: ' '{print $2}' | awk '{print $6}' | sed 's/\x1b\[[0-9;]*m//g')

        geometry_info+=$"Name:$name "
        geometry_info+=$"Mode:$mode "
        geometry_info+=$"Pos:$pos "
        geometry_info+=$"Geometry:$geometry "
        geometry_info+=$"Rotation:$rotation "
    done < <(kscreen-doctor -o | grep -E "$grep_pattern" | grep 'Geometry:')

    echo "$geometry_info"
}

set_output_mode() {
    primary_info=$(extract_geometry "$PRIMARY_PORT_PATTERN")
    hdmi_info=$(extract_geometry "HDMI")

    primary_name=$(echo $primary_info | awk -F 'Name:' '{print $2}' | awk '{print $1}')
    primary_mode=$(echo $primary_info | awk -F 'Mode:' '{print $2}' | awk '{print $1}')
    primary_pos=$(echo $primary_info | awk -F 'Pos:' '{print $2}' | awk '{print $1}')
    primary_geometry=$(echo $primary_info | awk -F 'Geometry:' '{print $2}' | awk '{print $1}')
    primary_rotation=$(echo $primary_info | awk -F 'Rotation:' '{print $2}' | awk '{print $1}')

    hdmi_name=$(echo $hdmi_info | awk -F 'Name:' '{print $2}' | awk '{print $1}')
    hdmi_mode=$(echo $hdmi_info | awk -F 'Mode:' '{print $2}' | awk '{print $1}')
    hdmi_pos=$(echo $hdmi_info | awk -F 'Pos:' '{print $2}' | awk '{print $1}')
    hdmi_geometry=$(echo $hdmi_info | awk -F 'Geometry:' '{print $2}' | awk '{print $1}')
    hdmi_rotation=$(echo $hdmi_info | awk -F 'Rotation:' '{print $2}' | awk '{print $1}')

    need_set_pos=false
    if [ "$hdmi_pos" != "1920,0" ];then
        need_set_pos=true
    elif [ "$primary_pos" != "0,0" ];then
        need_set_pos=true
    fi
    if $need_set_pos; then
        kscreen-doctor output.$primary_name.position.0,0 output.$hdmi_name.position.1920,0 > /dev/null 2>&1
    fi

    if [ "$primary_geometry" != "1920x1080" ] || [ "$hdmi_geometry" != "1920x1080" ];then
        if [ "$primary_rotation" != "1" ] || [ "$hdmi_rotation" != "1" ];then
            kscreen-doctor output.$primary_name.rotation.none output.$hdmi_name.rotation.none > /dev/null 2>&1
        else
            kscreen-doctor output.$primary_name.mode.$primary_mode output.$hdmi_name.mode.$primary_mode > /dev/null 2>&1
        fi
    fi

    if ! xrandr | grep -E "$PRIMARY_PORT_PATTERN" | grep primary > /dev/null;then
        xrandr --output $primary_name --primary
    fi
}

check_output_mode() {
    declare -A output_map
    input=$(xrandr --listmonitors  | grep -v "Monitors")
    while IFS= read -r entry; do
        device=$(echo "$entry" | awk '{print $4}')
        coordinates=$(echo "$entry" | awk '{print $3}')
        formatted_coordinates=$(echo "$coordinates" | awk -F '+' '{print $2,$3}')

        if [[ "$device" == *"VGA"* || "$device" == *"DisplayPort"* ]]; then
            primary_pos=$formatted_coordinates
        fi

        output_map["$device"]=$formatted_coordinates
    done <<< "$input"
    output_mode_clone=true
    for device in "${!output_map[@]}"; do
        if [ "${output_map[$device]}" != "0 0" ]; then
            xephyr_output_name=$device
            cat <<EOF >> $config_file
output:$xephyr_output_name
display:$xephyr_display
EOF
            output_mode_clone=false
        fi
    done

    if [ $output_mode_clone = "true" ];then
        echo "当前显示模式为镜像，请切换到拓展模式"
        exit
    else
        if ! xrandr | grep -E "$PRIMARY_PORT_PATTERN" | grep primary > /dev/null; then
            echo "拓展模式下请将VGA或DisplayPort设置为主屏幕"
            exit
        fi

        if [ "$primary_pos" != "0 0" ]; then
            echo "请将VGA或DisplayPort放置在(0,0)位置"
            exit
        fi
    fi
}

save_touch_info() {
    declare -A device_map

    while IFS= read -r name && IFS= read -r id <&3; do
        if (grep -qE "$TOUCH_REGEX" <<< "$name"); then
            device_map["$name"]=$id
        fi
    done < <(xinput list --name-only) 3< <(xinput list --id-only)

    for name in "${!device_map[@]}"; do
        if grep -qE "$TOUCH_REGEX" <<< "$name" && ! grep -qE 'Mouse' <<< "$name" && ! grep -qE 'Keyboard' <<< "$name" && ! grep -qE 'UNKNOWN' <<< "$name"; then
            if [ -z "$xephyr_touch_devID" ] || ((xephyr_touch_devID < ${device_map["$name"]})); then
                xephyr_touch_devID="${device_map["$name"]}"
                xephyr_touch_devName="$name"
                cat <<EOF >> $config_file
TouchName:$xephyr_touch_devName
TouchID:$xephyr_touch_devID
EOF

            fi
        fi
    done
}


save_input_info() {
    local reattachType=$1
    declare -A device_map
    local config_entries_virtual=""
    local config_entries_xephyr=""


    while IFS= read -r name && IFS= read -r id <&3; do
        if (grep -iq 'Keyboard' <<< "$name" || grep -q 'Wireless' <<< "$name" || grep -iq 'Mouse' <<< "$name") && ! grep -q 'Control' <<< "$name"; then
            device_map["$name"]=$id
        fi
    done < <(xinput list --name-only) 3< <(xinput list --id-only)

    for name in "${!device_map[@]}"; do
        if grep -iq 'Mouse' <<< "$name" && ! grep -qE "$TOUCH_REGEX" <<< "$name"; then
            pointer_devID="${device_map["$name"]}"
            pointer_devName="$name"

            if ! grep -q "$pointer_devName" "$config_file"; then
                case "$reattachType" in
                    "Virtual" )
                        echo -e "${RED}主屏鼠标$pointer_devID:$pointer_devName${RESET}"
                        config_entries_virtual+="VirtualMouseName:$pointer_devName\n"
                        config_entries_virtual+="VirtualMouseID:$pointer_devID\n"
                        ;;
                    "Xephyr" )
                        echo -e "${RED}副屏鼠标$pointer_devID:$pointer_devName${RESET}"
                        config_entries_xephyr+="XephyrMouseName:$pointer_devName\n"
                        config_entries_xephyr+="XephyrMouseID:$pointer_devID\n"
                        ;;
                esac
            fi
        elif grep -q 'Keyboard' <<< "$name"; then
            keyboard_devID="${device_map["$name"]}"
            keyboard_devName="$name"

            if ! grep -q "$keyboard_devName" "$config_file"; then
                case "$reattachType" in
                    "Virtual" )
                        echo -e "${RED}主屏键盘$keyboard_devID:$keyboard_devName${RESET}"
                        config_entries_virtual+="VirtualKeyboardName:$keyboard_devName\n"
                        config_entries_virtual+="VirtualKeyboardID:$keyboard_devID\n"
                        ;;
                    "Xephyr" )
                        echo -e "${RED}副屏键盘$keyboard_devID:$keyboard_devName${RESET}"
                        config_entries_xephyr+="XephyrKeyboardName:$keyboard_devName\n"
                        config_entries_xephyr+="XephyrKeyboardID:$keyboard_devID\n"
                        ;;
                esac
            fi
        fi
    done


    case "$reattachType" in
        "Virtual" )
            if [ -n "$config_entries_virtual" ]; then
                echo -e "$config_entries_virtual" >> "$config_file"
            fi
            ;;
        "Xephyr" )
            if [ -n "$config_entries_xephyr" ]; then
                echo -e "$config_entries_xephyr" >> "$config_file"
            fi
            ;;
    esac
}

update_input_id() {
    declare -A device_map

    while IFS= read -r name && IFS= read -r id <&3; do
        if (grep -iq 'USB' <<< "$name" || grep -q 'Wireless' <<< "$name") && ! grep -q 'Control' <<< "$name"; then
            device_map["$name"]=$id
        fi
    done < <(xinput list --name-only) 3< <(xinput list --id-only)

    update_config() {
        local device_name="$1"
        local config_key="$2"

        for name in "${!device_map[@]}"; do
            if [[ "$name" == *"$device_name"* ]]; then
                sed -i "s/^$config_key:.*/$config_key:${device_map["$name"]}/" "$config_file"
                break
            fi
        done
    }

    x_pointer_devName=$(grep XephyrMouseName "$config_file" | cut -d':' -f2- | xargs)
    x_keyboard_devName=$(grep XephyrKeyboardName "$config_file" | cut -d':' -f2- | xargs)
    v_pointer_devName=$(grep VirtualMouseName "$config_file" | cut -d':' -f2- | xargs)
    v_keyboard_devName=$(grep VirtualKeyboardName "$config_file" | cut -d':' -f2- | xargs)

    update_config "$x_pointer_devName" "XephyrMouseID"
    update_config "$x_keyboard_devName" "XephyrKeyboardID"
    update_config "$v_pointer_devName" "VirtualMouseID"
    update_config "$v_keyboard_devName" "VirtualKeyboardID"
}

update_touch_id() {
    declare -A device_map

    while IFS= read -r name && IFS= read -r id <&3; do
        if grep -qE "$TOUCH_REGEX" <<< "$name" && ! grep -qE 'Mouse' <<< "$name" && ! grep -qE 'Keyboard' <<< "$name" && ! grep -qE 'UNKNOWN' <<< "$name"; then
            device_map["$name"]=$id
        fi
    done < <(xinput list --name-only) 3< <(xinput list --id-only)

    update_config() {
        local device_name="$1"
        local config_key="$2"

        for name in "${!device_map[@]}"; do
            if [[ "$name" == *"$device_name"* ]]; then
                sed -i "s/^$config_key:.*/$config_key:${device_map["$name"]}/" "$config_file"
                break
            fi
        done
    }

    TouchName=$(grep TouchName "$config_file" | cut -d':' -f2- | xargs)
    update_config "$TouchName" "TouchID"
}

read_device_id() {
    if [ -f $config_file ];then
        xephyr_pointer_devID=$(cat $config_file | grep XephyrMouseID | cut -d':' -f2-)
        xephyr_pointer_devName=$(cat $config_file | grep XephyrMouseName | cut -d':' -f2-)
        xephyr_keyboard_devID=$(cat $config_file | grep XephyrKeyboardID | cut -d':' -f2-)
        xephyr_keyboard_devName=$(cat $config_file | grep XephyrKeyboardName | cut -d':' -f2-)
        xephyr_touch_devID=$(cat $config_file | grep TouchID | cut -d':' -f2-)
        xephyr_touch_devName=$(cat $config_file | grep TouchName | cut -d':' -f2-)
    fi
}

get_device() {
    mouse_device=$(xinput list --name-only | grep -i 'mouse' | grep -vE "$TOUCH_REGEX")
    echo -e "mouse : \n$mouse_device"
    keyboard_device=$(xinput | grep "slave  keyboard"| grep Keyboard  | grep -v Control)
    echo -e "keyboard : \n$keyboard_device"
}

get_device_count() {
    mouse_count=$(xinput list --name-only | grep -i 'mouse' | grep -vE "$TOUCH_REGEX" | wc -l)
    keyboard_count=$(xinput | grep "slave  keyboard"| grep Keyboard  | grep -v Control | wc -l)
}

check_input_count() {
    target_count=$1

    stdbuf -oL udevadm monitor --subsystem-match=input --property | while read -r line; do
        if echo "$line" | grep -q 'ACTION=.*add\|remove'; then
            sleep 1
            get_device_count
            if [ "$mouse_count" -eq "$target_count" ] && [ "$keyboard_count" -eq "$target_count" ]; then
                pid=$(pgrep udevadm)
                kill $pid
                break
            fi
        fi
    done
}

begin_get_input() {
    get_device_count
    if [ "$mouse_count" -ne 1 ] || [ "$keyboard_count" -ne 1 ]; then
        echo -e "${GREEN}请检查您的设备，确保只有一个键盘和一个鼠标连接${RESET}"
        check_input_count 1
    fi

    get_device_count
    if [ "$mouse_count" -eq 1 ] && [ "$keyboard_count" -eq 1 ]; then
        save_input_info "Virtual"
        echo -e "${GREEN}请插入第二套键鼠设备${RESET}"
        check_input_count 2
        save_input_info "Xephyr"
    fi
}

case "$args" in
    "" | "new")
        #log_time "main[new]: start"
        [ -f $config_file ] && rm $config_file &&  touch $config_file
        check_user_info
        check_ctuser_home
        set_output_mode
        check_output_mode

        if ! xinput | grep -q "xephyr"; then
            xinput create-master "xephyr"
        fi

        cat <<EOF >> $config_file
useDoubleInput:$use_double_input
EOF
        if [ "$use_double_input" = "true" ];then
            begin_get_input
            read_device_id
            reattach_input_device
        else
            save_touch_info
            reattach_touch_device
        fi

        cp $config_file $tmp_config_file
        killall ukui-settings-daemon
        [ "$user_info_flag" = "true" ] && xephyr_start
        #log_time "main[new]: end"
        ;;
    "last")
        #log_time "main[last]: start"
        check_user_info
        check_ctuser_home
        set_output_mode
        check_output_mode

        if ! xinput | grep -q "xephyr"; then
            xinput create-master "xephyr"
        fi

        use_double_input=$(cat $config_file | grep useDoubleInput | awk -F: '{print $2}')
        update_input_id
        update_touch_id
        read_device_id

        if [ "$use_double_input" = "true" ];then
            reattach_input_device
        else
            reattach_touch_device
        fi

        cp $config_file $tmp_config_file
        [ "$user_info_flag" = "true" ] && xephyr_start
        #log_time "main[last]: end"
        ;;
    "clean")
        read_device_id
        clean_xephyr
        ;;

    "hot")
        use_double_input=$(cat $config_file | grep useDoubleInput | awk -F: '{print $2}')
        update_touch_id
        read_device_id
        [ -n "$xephyr_touch_devID" ] && xinput reattach "$xephyr_touch_devID" "xephyr pointer"
        touch_device_map
        cp $config_file $tmp_config_file
        ;;

    "reattach")
        update_input_id
        read_device_id
        reattach_input_device
        cp $config_file $tmp_config_file
        ;;
    "read")
        get_device
        ;;
    *)
        echo "Options:"
        echo "   new       create isolated user environment"
        echo "   clean     clean isolated user environment"
        echo "   hot       reattach touch device to xephyr environment"
        echo "   reattach  reattach USB device to xephyr environment"
        exit
        ;;
esac




