#!/bin/sh

# Определение директории, где находится xkeen
script_dir="$(cd "$(dirname "$0")" && pwd)"

# Скрываем основную директорию xkeen
install_xkeen_rename() {
    source_dir="_xkeen"
    target_dir=".xkeen"
    source_path="$script_dir/$source_dir"
    target_path="$script_dir/$target_dir"

    if [ -d "$source_path" ]; then
        if [ -d "$target_path" ]; then
            rm -rf "$target_path" 2>/dev/null
        fi
        mv "$source_path" "$target_path"
    fi
    rm "/opt/root/install.sh" 2>/dev/null
}
install_xkeen_rename

add_chmod_init() {
    [ -f "$initd_file" ] && chmod +x "$initd_file"
}

# Подсчет количества логических команд (параметров, начинающихся с - или --)
LOGICAL_CMD_COUNT=0
for arg in "$@"; do
    case "$arg" in
        -*) LOGICAL_CMD_COUNT=$((LOGICAL_CMD_COUNT + 1)) ;;
    esac
done

# Функция умной очистки экрана
smart_clear() {
    # Очищаем экран, только если запущена одна логическая команда
    if [ "$LOGICAL_CMD_COUNT" -le 1 ]; then
        clear
    fi
}

for arg in "$@"; do
    [ "$arg" = "-toff" ] && export XKEEN_TIMEOUT_OFF=1
    [ "$arg" = "-restart" ] && apply="restart"
    case "$arg" in
        -restart|-start|-stop) detach_eligible=true ;;
    esac
done

# Self-detach в новую session/pgid когда вызвали без TTY (ssh без -t, cron, CGI)
# чтобы форсированный обрыв caller-сессии не убивал начальные проверки.
# Подробности в commit-message. XKEEN_FOREGROUND=1 отключает детач для callers
# требующих синхронной семантики (скрипты с && cleanup).
if [ -n "$detach_eligible" ] && [ -z "$XKEEN_DETACHED" ] \
   && [ ! -t 0 ] && [ ! -t 1 ] && [ -z "$XKEEN_FOREGROUND" ]; then
    export XKEEN_DETACHED=1
    log_dir="/opt/var/log"
    [ -d "$log_dir" ] || mkdir -p "$log_dir"
    log="$log_dir/xkeen-detached.log"
    {
        echo
        echo "=== $(date '+%F %T') $0 $* ==="
    } >>"$log"
    start-stop-daemon -S -b -n "xkdtch.$$" \
        -x "$0" -- "$@" \
        >>"$log" 2>&1
    echo "  Запуск в фоновом режиме, лог: $log" >&2
    exit 0
fi

get_state_arg() {
    if [ "$1" = "on" ] || [ "$1" = "off" ]; then
        echo "$1"
    fi
}

# Импортируем модули
. "$script_dir/.xkeen/import.sh"

# -toff действует только в этом процессе и его потомках: пользователь без
# root больше не может отключить curl timeouts общим файлом в /tmp.
trap 'exit 1' INT TERM

xkeen_info() {
    # Проверяем версию XKeen
    info_version_xkeen

    # Проверяем актуальность XKeen
    info_compare_xkeen
}

xkeen_set_info() {
    # Определяем архитектуру процессора
    info_cpu

    # Проверяем установку Xray
    info_xray

    # Проверяем установку Mihomo
    info_mihomo

    # Проверяем установленные базы GeoSite
    info_geosite

    # Проверяем установленные базы GeoiIP
    info_geoip

    # Проверяем статус автообновления
    info_cron
}

# Проверяем запущен ли прокси-клиент
is_proxy_running() { pidof xray >/dev/null 2>&1 || pidof mihomo >/dev/null 2>&1; }

while [ $# -gt 0 ]; do
    case "$1" in

        -i|-install)    # Запуск полного цикла установки
            info_firmware
            test_connection
            check_health
            test_entware
            test_github
            sleep 2

            smart_clear
            echo
            check_keen_mode
            if [ -n "$keen_mode" ]; then
                echo -e "  ${red}Ошибка${reset}: Установка XKeen возможна только на Keenetic в режиме ${green}роутера${reset}"
                exit 1
            fi

            echo -e "  Запуск полного цикла установки ${yellow}XKeen${reset}"

            init_directories
            xkeen_set_info
            logs_cpu_info_console

            case "$architecture" in
                arm64-v8a|mips32le|mips32) ;;
                *) exit 1 ;;
            esac

            location_entware_storage
            preinstall_warn

            choice_add_proxy_cores

            if [ "$add_xray" = "true" ] && [ "$xray_installed" != "installed" ]; then
                check_free_space xray || add_xray="false"
            fi

            if [ "$add_xray" = "true" ]; then
                smart_clear
                download_xray
            else
                command -v xray >/dev/null 2>&1 || bypass_xray="true"
            fi

            if [ -z "$bypass_xray" ]; then
                if [ -f "$install_dir/xray" ]; then
                    chmod +x "$install_dir/xray" 2>/dev/null
                else
                    if ! install_xray; then
                        bypass_xray="true"
                    fi
                fi
                info_xray
            fi

            if [ "$xray_installed" = "installed" ]; then
                smart_clear
                echo
                xray_conf_install
            fi

            if [ "$add_mihomo" = "true" ] && [ "$mihomo_installed" != "installed" ]; then
                check_free_space mihomo || add_mihomo="false"
            fi

            if [ "$add_mihomo" = "true" ]; then
                smart_clear
                if ! download_mihomo; then
                    bypass_mihomo="true"
                fi
            else
                command -v mihomo >/dev/null 2>&1 || bypass_mihomo="true"
            fi

            if [ -z "$bypass_mihomo" ]; then
                if [ -f "$install_dir/mihomo" ]; then
                    chmod +x "$install_dir/mihomo" 2>/dev/null
                else
                    if ! install_mihomo; then
                        bypass_mihomo="true"
                    fi
                fi
                info_mihomo
            fi

            if [ "$mihomo_installed" = "installed" ]; then
                add_mihomo_config
            fi

            if [ "$mihomo_installed" != "installed" ] && [ "$xray_installed" != "installed" ]; then
                echo
                echo -e "  ${red}Ошибка${reset}: Установка прервана. Не установлено ни одного ядра проксирования (Xray или Mihomo)"
                exit 1
            fi

            if [ "$xray_installed" = "installed" ]; then
                geofile_update="true"

                smart_clear
                # Устанавливаем GeoSite
                choice_geosite
                delete_geosite
                install_geosite
                sleep 2

                smart_clear
                # Устанавливаем GeoIP
                choice_geoip
                delete_geoip
                install_geoip
                sleep 2
            fi

            if [ "$xray_installed" = "installed" ] || [ "$mihomo_installed" = "installed" ]; then
                smart_clear
                # Устанавливаем GeoIPSET
                install_geoipset init
                sleep 2
            fi

            if [ "$bypass_cron_geosite" = "false" ] || [ "$bypass_cron_geoip" = "false" ] || [ "$bypass_cron_geoipset" = "false" ]; then
                smart_clear
                # Настраиваем автоматические обновления
                choice_update_cron
                update_cron_geofile_task
                [ "$choice_geofile_cron_select" = "true" ] && smart_clear
                choice_cron_time
                install_cron
                sleep 2
            fi

            # Создаем init для cron
            "$initd_dir/S05crond" stop >/dev/null 2>&1
            [ -e "$initd_dir/S05crond" ] && rm -f "$initd_dir/S05crond"
            register_cron_initd
            "$initd_dir/S05crond" start >/dev/null 2>&1

            smart_clear

            if [ -z "$bypass_xray" ]; then
                delete_register_xray
                echo
                echo -e "  Выполняется регистрация ${yellow}Xray${reset}"
                register_xray_list
                logs_register_xray_list_info_console
                register_xray_control
                logs_register_xray_control_info_console
                register_xray_status
                logs_register_xray_status_info_console
                sleep 2
            fi

            if [ -z "$bypass_mihomo" ]; then
                delete_register_mihomo
                delete_register_yq
                echo
                echo -e "  Выполняется регистрация ${yellow}Mihomo${reset}"
                register_mihomo_list
                logs_register_mihomo_list_info_console
                register_mihomo_control
                logs_register_mihomo_control_info_console
                register_mihomo_status
                logs_register_mihomo_status_info_console
                register_yq_list
                logs_register_yq_list_info_console
                register_yq_control
                logs_register_yq_control_info_console
                register_yq_status
                logs_register_yq_status_info_console
                sleep 2
            fi

            if [ "$xray_installed" = "installed" ] || [ "$mihomo_installed" = "installed" ]; then
                delete_register_xkeen
                echo
                echo -e "  Выполняется регистрация ${yellow}XKeen${reset}"
                register_xkeen_list
                logs_register_xkeen_list_info_console
                register_xkeen_control
                logs_register_xkeen_control_info_console
                register_xkeen_status
                logs_register_xkeen_status_info_console

                fixed_register_packages

                migrate_ports_from_initd
                register_xkeen_initd
                create_xkeen_cfg
                sleep 2

                smart_clear
                choice_autostart_xkeen
            fi

            if [ "$xray_installed" != "installed" ] && [ "$mihomo_installed" = "installed" ]; then
                if [ -f "$install_dir/mihomo" ] && [ -f "$install_dir/yq" ] && grep -q 'name_client="xray"' "$initd_file"; then
                    sed -i 's/name_client="xray"/name_client="mihomo"/' "$initd_file"
                fi
            elif  [ "$xray_installed" = "installed" ] && [ "$mihomo_installed" != "installed" ]; then
                if [ -f "$install_dir/xray" ] && grep -q 'name_client="mihomo"' "$initd_file"; then
                    sed -i 's/name_client="mihomo"/name_client="xray"/' "$initd_file"
                fi
            fi

            add_chmod_init

            if is_proxy_running; then
                "$initd_file" restart on >/dev/null 2>&1
            fi

            # Удаляем временные файлы
            delete_tmp
            sleep 2

            smart_clear
            echo
            echo -e "  ${green}Установка XKeen завершена!${reset}"

            if [ "$xray_installed" = "installed" ] || [ "$mihomo_installed" = "installed" ]; then
                if grep -q 'name_client="xray"' "$initd_file"; then
                    echo -e "  1. Настройте конфигурацию Xray по пути '${yellow}$xray_conf_dir/${reset}'"
                    echo -e "  2. Запустите XKeen командой ${yellow}xkeen -start${reset}"
                    echo -e "  3. ${green}Enjoy!${reset}"
                    echo
                elif grep -q 'name_client="mihomo"' "$initd_file"; then
                    echo -e "  1. Настройте конфигурацию Mihomo в файле '${yellow}$mihomo_conf_dir/config.yaml${reset}'"
                    echo -e "  2. Запустите XKeen командой ${yellow}xkeen -start${reset}"
                    echo -e "  3. ${green}Enjoy!${reset}"
                    echo
                fi
            fi

            if [ "$xray_installed" = "installed" ] && [ "$mihomo_installed" = "installed" ]; then
                if grep -q 'name_client="xray"' "$initd_file"; then
                    echo -e "  Если хотите переключить XKeen на ядро ${yellow}Mihomo${reset}"
                    echo
                    echo -e "  1. Настройте конфигурацию Mihomo в файле '${yellow}$mihomo_conf_dir/config.yaml${reset}'"
                    echo -e "  2. Переключите ядро проксирования командой ${yellow}xkeen -mihomo${reset}"
                    echo -e "  3. Запустите XKeen командой ${yellow}xkeen -start${reset}"
                    echo -e "  4. ${green}Enjoy!${reset}"
                elif grep -q 'name_client="mihomo"' "$initd_file"; then
                    echo -e "  Если хотите переключить XKeen на ядро ${yellow}Xray${reset}"
                    echo
                    echo -e "  1. Настройте конфигурацию Xray по пути '${yellow}$xray_conf_dir/${reset}'"
                    echo -e "  2. Переключите ядро проксирования командой ${yellow}xkeen -xray${reset}"
                    echo -e "  3. Запустите XKeen командой ${yellow}xkeen -start${reset}"
                    echo -e "  4. ${green}Enjoy!${reset}"
                fi
            echo
            fi

            echo -e "  Для вывода Справки выполните ${yellow}xkeen -h${reset}"
        ;;


        -io)    # Установка XKeen OffLine
            info_firmware
            smart_clear
            echo
            check_keen_mode
            if [ -n "$keen_mode" ]; then
            echo -e "  ${red}Ошибка${reset}: Установка XKeen возможна только на Keenetic в режиме ${green}роутера${reset}"
                exit 1
            fi
            echo "  Установка XKeen OffLine"

            init_directories
            xkeen_set_info
            logs_cpu_info_console

            case "$architecture" in
                arm64-v8a|mips32le|mips32) ;;
                *) exit 1 ;;
            esac

            if [ -f "$install_dir/xray" ]; then
                chmod +x "$install_dir/xray"
            elif [ -f "$install_dir/mihomo" ]; then
                chmod +x "$install_dir/mihomo"
                if [ -f "$install_dir/yq" ]; then
                    chmod +x "$install_dir/yq"
                else
                    echo -e "  ${red}Не найден${reset} парсер конфигурационных файлов Mihomo - Yq"
                    exit 1
                fi
            else
                smart_clear
                echo
                echo -e "  ${red}Не найдено ядро проксирования xray или mihomo${reset}"
                echo
                echo -e "  Если планируете использовать ядро xray, поместите бинарник ${yellow}xray${reset}\n  архитектуры ${green}$architecture${reset} в директорию /opt/sbin/ и начните установку снова"
                echo -e "  Страница загрузок xray: ${yellow}https://github.com/XTLS/Xray-core/releases/latest${reset}"
                echo
                echo -e "  Если планируете использовать ядро mihomo, поместите бинарники ${yellow}mihomo${reset} и ${yellow}yq${reset}\n  архитектуры ${green}$architecture${reset} в директорию /opt/sbin/ и начните установку снова"
                echo -e "  Страница загрузок mihomo: ${yellow}https://github.com/MetaCubeX/mihomo/releases/latest${reset}"
                echo -e "  Страница загрузок yq: ${yellow}https://github.com/mikefarah/yq/releases/latest${reset}"
                echo
                exit 1
            fi

            if [ -f "$install_dir/xray" ]; then
                xray_conf_install

                if [ ! -d "$geo_dir" ]; then
                    mkdir -p "$geo_dir"
                fi

                smart_clear
                delete_register_xray
                info_xray
                echo
                echo -e "  Выполняется регистрация ${yellow}Xray${reset}"
                register_xray_list
                logs_register_xray_list_info_console
                register_xray_control
                logs_register_xray_control_info_console
                register_xray_status
                logs_register_xray_status_info_console
            fi

            if [ -f "$install_dir/mihomo" ]; then
                add_mihomo_config
                delete_register_mihomo
                delete_register_yq
                info_mihomo
                echo
                echo -e "  Выполняется регистрация ${yellow}Mihomo${reset}"
                register_mihomo_list
                logs_register_mihomo_list_info_console
                register_mihomo_control
                logs_register_mihomo_control_info_console
                register_mihomo_status
                logs_register_mihomo_status_info_console
                register_yq_list
                logs_register_yq_list_info_console
                register_yq_control
                logs_register_yq_control_info_console
                register_yq_status
                logs_register_yq_status_info_console
                sleep 2
            fi

            smart_clear
            delete_register_xkeen
            echo
            echo -e "  Выполняется регистрация ${yellow}XKeen${reset}"
            register_xkeen_list
            logs_register_xkeen_list_info_console

            register_xkeen_control
            logs_register_xkeen_control_info_console

            register_xkeen_status
            logs_register_xkeen_status_info_console

            migrate_ports_from_initd
            register_xkeen_initd
            create_xkeen_cfg

            fixed_register_packages

            smart_clear
            choice_autostart_xkeen
            add_chmod_init

            if is_proxy_running; then
                "$initd_file" restart on >/dev/null 2>&1
            fi

            # Удаляем временные файлы
            echo
            delete_tmp
            sleep 2

            smart_clear
            echo
            echo -e "  ${green}Установка XKeen завершена!${reset}"
            echo
            echo -e "  Для использования ядра '${yellow}$Xray${reset}'"
            echo -e "  1. Поместите необходимые геофайлы в директорию '${yellow}$geo_dir/${reset}'"
            echo -e "  2. Настройте конфигурацию Xray по пути '${yellow}$xray_conf_dir/${reset}'"
            echo -e "  3. Запустите XKeen командой ${yellow}xkeen -start${reset}"
            echo -e "  4. ${green}Enjoy!${reset}"
            echo
            echo -e "  Для использования ядра ${yellow}Mihomo${reset}"
            echo -e "  1. Настройте конфигурацию Mihomo в файле '${yellow}$mihomo_conf_dir/config.yaml${reset}'"
            echo -e "  2. Переключите ядро проксирования командой ${yellow}xkeen -mihomo${reset}"
            echo -e "  3. Запустите XKeen командой ${yellow}xkeen -start${reset}"
            echo -e "  4. ${green}Enjoy!${reset}"
            echo
            echo -e "  Для вывода Справки выполните ${yellow}xkeen -h${reset}"
        ;;


        -ug)    # Обновление баз GeoFile/GeoIPSET
            test_connection
            check_health
            test_github
            sleep 2

            smart_clear
            echo
            echo "  Обновление установленных баз GeoFile/GeoIPSET"

            info_geosite
            info_geoip
            if 
                [ "$update_refilter_geosite" = "true" ] || \
                [ "$update_v2fly_geosite" = "true" ] || \
                [ "$update_zkeen_geosite" = "true" ] || \
                [ "$update_refilter_geoip" = "true" ] || \
                [ "$update_v2fly_geoip" = "true" ] || \
                [ "$update_zkeenip_geoip" = "true" ] || \
                [ -f "$ru_exclude_ipv4" ]; then

                echo
                geofiles_update_state
                install_geosite
                install_geoip
                update_user_geofiles
                install_geoipset update

                if pidof mihomo >/dev/null; then
                    # GeoIPSET загружается в ipset при старте — нужен reapply.
                    "$initd_file" restart on >/dev/null 2>&1
                elif pidof xray >/dev/null; then
                    "$initd_file" restart on >/dev/null 2>&1
                fi

                echo -e "  Обновление установленных баз GeoFile/GeoIPSET ${green}завершено${reset}"
            else
                echo -e "  ${red}Не обнаружены${reset} базы GeoFile/GeoIPSET для обновления"
            fi
        ;;


        -uk)    # Обновление XKeen
            test_connection
            check_health	
            test_entware
            test_github
            sleep 2

            smart_clear
            echo
            echo "  Проверка обновлений XKeen"
            xkeen_info
            xkeen_set_info

            if [ "$xkeen_build" != "Stable" ]; then
                download_func="download_xkeen_dev"
            else
                if [ "$info_compare_xkeen" = "actual" ]; then
                    echo "  Нет доступных обновлений XKeen"
                    exit 0
                else
                    echo -e "  Найдена новая версия ${yellow}XKeen${reset}"
                    download_func="download_xkeen"
                fi
            fi

            backup_xkeen
            "$download_func"

            if ! install_xkeen; then
                echo
                echo -e "  Установка новой версии XKeen ${red}не выполнена${reset}"
                delete_tmp
                exit 1
            fi

            # Перезапуск скрипта
            grep -E "^\s*-uk_post_update\s*\)" "$0" > /dev/null && exec sh "$0" -uk_post_update
        ;;


        -uk_post_update)
            . "$xkeen_dir/import.sh"
            init_directories
            xkeen_set_info
            new_features
            register_cron_initd
            migrate_ports_from_initd
            register_xkeen_initd
            create_xkeen_cfg
            chmod 700 "$xkeen_cfg" 2>/dev/null
            chmod 600 "$xkeen_config" 2>/dev/null
            choice_cancel_cron_select=true
            update_cron_geofile_task
            smart_clear
            echo

            echo -e "  Выполняется отмена регистрации предыдущей версии ${yellow}XKeen${reset}"
            delete_register_xkeen
            logs_delete_register_xkeen_info_console

            echo -e "  Выполняется регистрация новой версии ${yellow}XKeen${reset}"
            register_xkeen_list
            logs_register_xkeen_list_info_console

            register_xkeen_control
            logs_register_xkeen_control_info_console

            register_xkeen_status
            logs_register_xkeen_status_info_console

            if is_proxy_running; then
                "$initd_file" restart on >/dev/null 2>&1
            fi

            fixed_register_packages
            echo
            delete_tmp

            echo -e "  Обновление XKeen ${green}выполнено${reset}"
            version_xkeen
        ;;


        -ux)    # Обновление или установка ядра Xray
            check_free_space xray || exit 1
            test_connection
            check_health
            test_github
            info_cpu
            sleep 2
            smart_clear
            info_xray

            [ "$xray_installed" = "installed" ] && echo && echo -e "  В роутере установлен Xray версии ${yellow}$xray_current_version${reset}"
            download_xray

            if [ -z "$bypass_xray" ]; then
                if ! install_xray; then
                    echo
                    delete_tmp
                    echo -e "  ${red}Ошибка${reset}: Установка Xray не выполнена"
                    exit 1
                fi

                if [ "$xray_installed" = "installed" ]; then
                    echo -e "  Выполняется отмена регистрации предыдущей версии ${yellow}Xray${reset}"
                    delete_register_xray
                    logs_delete_register_xray_info_console

                    info_xray
                    echo -e "  Выполняется регистрация новой версии ${yellow}Xray${reset}"
                    register_xray_list
                    logs_register_xray_list_info_console
                    register_xray_control
                    logs_register_xray_control_info_console
                    register_xray_status
                    logs_register_xray_status_info_console

                    sleep 2
                    if pidof xray >/dev/null; then
                        "$initd_file" restart on >/dev/null 2>&1
                    fi

                    echo
                    echo -e "  Обновление ядра Xray ${green}выполнено${reset}"
                else
                    xray_installed="installed"
                    info_xray

                    if [ -f "$install_dir/xray" ]; then
                        xray_conf_install
        
                        if [ ! -d "$geo_dir" ]; then
                            mkdir -p "$geo_dir"
                        fi

                        delete_register_xray
                        echo
                        echo -e "  Выполняется регистрация ${yellow}Xray${reset}"
                        register_xray_list
                        logs_register_xray_list_info_console
                        register_xray_control
                        logs_register_xray_control_info_console
                        register_xray_status
                        logs_register_xray_status_info_console
                        sleep 2
                        smart_clear
                        echo
                        echo -e "  Установка ядра ${yellow}Xray${reset} ${green}выполнена${reset}"
                    fi
                fi
            fi

            fixed_register_packages
            echo
            delete_tmp
        ;;


        -um)    # Обновление или установка ядра Mihomo
            check_free_space mihomo || exit 1
            test_connection
            check_health
            test_github
            info_cpu
            sleep 2
            smart_clear
            info_mihomo
            mihomo_was_installed="$mihomo_installed"

            [ "$mihomo_installed" = "installed" ] && echo && echo -e "  В роутере установлен Mihomo версии ${yellow}$mihomo_current_version${reset}"
            if ! download_mihomo; then
                echo
                delete_tmp
                exit 1
            fi

            if [ -z "$bypass_mihomo" ]; then
                if ! install_mihomo; then
                    echo
                    delete_tmp
                    echo -e "  ${red}Ошибка${reset}: Установка Mihomo не выполнена. См. сообщения выше"
                    exit 1
                fi
                info_mihomo

                if [ "$mihomo_installed" != "installed" ]; then
                    echo
                    delete_tmp
                    echo -e "  ${red}Ошибка${reset}: Mihomo не установлен (отсутствует обязательный Yq или бинарник Mihomo)"
                    exit 1
                elif [ "$mihomo_was_installed" = "installed" ]; then
                    echo -e "  Выполняется отмена регистрации предыдущей версии ${yellow}Mihomo${reset}"
                    delete_register_mihomo
                    delete_register_yq
                    logs_delete_register_mihomo_info_console
                    logs_delete_register_yq_info_console

                    info_mihomo
                    echo -e "  Выполняется регистрация новой версии ${yellow}Mihomo${reset}"
                    register_mihomo_list
                    logs_register_mihomo_list_info_console
                    register_mihomo_control
                    logs_register_mihomo_control_info_console
                    register_mihomo_status
                    logs_register_mihomo_status_info_console
                    register_yq_list
                    logs_register_yq_list_info_console
                    register_yq_control
                    logs_register_yq_control_info_console
                    register_yq_status
                    logs_register_yq_status_info_console

                    if pidof mihomo >/dev/null; then
                        "$initd_file" restart on >/dev/null 2>&1
                    fi
                    echo
                    echo -e "  Обновление ядра ${yellow}Mihomo${reset} ${green}выполнено${reset}"
                else
                    info_mihomo
                    add_mihomo_config
                    delete_register_mihomo
                    delete_register_yq
                    echo
                    echo -e "  Выполняется регистрация ${yellow}Mihomo${reset}"
                    register_mihomo_list
                    logs_register_mihomo_list_info_console
                    register_mihomo_control
                    logs_register_mihomo_control_info_console
                    register_mihomo_status
                    logs_register_mihomo_status_info_console
                    register_yq_list
                    logs_register_yq_list_info_console
                    register_yq_control
                    logs_register_yq_control_info_console
                    register_yq_status
                    logs_register_yq_status_info_console
                    sleep 2
                    smart_clear
                    echo
                    echo -e "  Установка ядра ${yellow}Mihomo${reset} ${green}выполнена${reset}"
                fi
            fi

            fixed_register_packages
            echo
            delete_tmp
        ;;


        -uy)    # Обновление или установка Yq
            test_connection
            check_health
            test_github
            info_cpu
            sleep 2
            smart_clear
            download_yq
            info_version_yq

            delete_register_yq
            logs_delete_register_yq_info_console
            info_version_yq
            echo -e "  Выполняется регистрация новой версии ${yellow}Yq${reset}"
            register_yq_list
            logs_register_yq_list_info_console
            register_yq_control
            logs_register_yq_control_info_console
            register_yq_status
            logs_register_yq_status_info_console
            sleep 2
            echo
            echo -e "  Установка ${yellow}Yq${reset} ${green}выполнена${reset}"

            fixed_register_packages
            echo
            delete_tmp
        ;;


        -ugc)    # Создать или изменить существующюю задачу автообновления баз GeoFile/GeoIPSET
            info_cron
            smart_clear
            echo
            echo -e "  Создание или изменение задачи автообновления баз ${yellow}GeoFile/GeoIPSET${reset}"
            choice_update_cron
            update_cron_geofile_task
            [ "$choice_geofile_cron_select" = "true" ] && smart_clear
            choice_cron_time
            install_cron
            delete_tmp
            echo -e "  Создание или изменение задачи автообновления баз GeoFile/GeoIPSET ${green}выполнено${reset}"
        ;;


        -ri)    # Пересоздать файл автозапуска XKeen
            smart_clear
            # Не останавливаем прокси и не rm initd заранее:
            # register_xkeen_initd сам делает mv→бэкап и мигрирует
            # name_client/порты/политики. Прежний rm убивал миграцию
            # и сбрасывал mihomo-пользователей на дефолтный xray.
            was_running=false
            is_proxy_running && was_running=true

            echo -e "  Создание файла автозапуска ${yellow}XKeen${reset}"
            sleep 1

            init_directories
            migrate_ports_from_initd
            register_xkeen_initd
            logs_register_xkeen_initd_info_console
            add_chmod_init

            echo
            echo -e "  Создание файла автозапуска XKeen ${green}выполнено${reset}"
            if [ "$was_running" = "true" ]; then
                echo -e "  Прокси работал до пересоздания — выполняется ${yellow}перезапуск${reset}"
                "$initd_file" restart on
            else
                echo -e "  Если конфигурация настроена, запустите проксирование командой '${yellow}xkeen -start${reset}'"
            fi
        ;;


        -dgc)    # Удалить задачу автообновления баз GeoFile/GeoIPSET
            info_cron
            smart_clear
            echo
            choice_for_remove="задачу автообновления баз GeoFile/GeoIPSET"
            choice_remove
            smart_clear
            echo
            echo -e "  Удаление задачи автообновления баз ${yellow}GeoFile/GeoIPSET${reset}"
            delete_cron_geofile
            logs_delete_cron_geofile_info_console
            echo
            delete_tmp
            echo -e "  Удаление задачи автообновления баз GeoFile/GeoIPSET ${green}выполнено${reset}"
        ;;


        -dx)    # Удалить Xray
            smart_clear
            echo
            choice_for_remove="Xray"
            choice_remove
            smart_clear
            echo
            command -v xray >/dev/null 2>&1 || { echo -e "  Xray ${red}не установлен${reset}"; exit 1; }
            echo -e "  Удаление ${yellow}Xray${reset}"

            "$initd_file" stop >/dev/null 2>&1
            opkg remove xray_s
            rm -f "$install_dir/xray"

            echo
            echo -e "  Удаление ${yellow}конфигурационных файлов Xray${reset}"

            delete_configs
            logs_delete_configs_info_console

            echo
            echo -e "  Удаление Xray ${green}выполнено${reset}"
        ;;


        -dm)    # Удалить Mihomo и Yq
            smart_clear
            echo
            choice_for_remove="Mihomo"
            choice_remove
            smart_clear
            echo
            command -v mihomo >/dev/null 2>&1 || { echo -e "  Mihomo ${red}не установлен${reset}"; exit 1; }
            echo -e "  Удаление ${yellow}Mihomo${reset}"

            "$initd_file" stop >/dev/null 2>&1
            opkg remove mihomo_s
            opkg remove yq_s
            rm -f "$install_dir/mihomo" "$install_dir/yq"
            rm -rf "$mihomo_conf_dir"

            echo
            echo -e "  Удаление Mihomo ${green}выполнено${reset}"
        ;;


        -dk)    # Удалить XKeen
            smart_clear
            echo
            choice_for_remove="XKeen"
            choice_remove

            smart_clear
            echo
            echo -e "  Удаление ${yellow}XKeen${reset}"
            opkg remove xkeen
            echo
            delete_tmp

            smart_clear
            echo
            delete_all

            smart_clear
            echo
            echo -e "  Удаление XKeen ${green}выполнено${reset}"
            echo
            echo -e "  Установить ${yellow}XKeen${reset} заново можно командами:"
            echo
            echo -e "  ${green}opkg update && opkg install curl tar && cd /tmp${reset}"
            echo -e "  ${green}"'sh -c "$(curl -sSL https://raw.githubusercontent.com/jameszeroX/XKeen/main/install.sh)"'"${reset}"


        ;;


        -dgi)    # Удалить GeoIP
            smart_clear
            choice_for_remove="GeoIP"
            choice_remove

            smart_clear
            echo
            echo -e "  Удаление всех баз ${yellow}GeoIP${reset}"

            delete_geoip_key
            logs_delete_geoip_info_console

            echo
            echo -e "  Удаление всех баз GeoIP ${green}выполнено${reset}"
        ;;


        -dgs)    # Удалить GeoSite
            smart_clear
            choice_for_remove="GeoSite"
            choice_remove

            smart_clear
            echo
            echo -e "  Удаление всех баз ${yellow}GeoSite${reset}"

            delete_geosite_key
            logs_delete_geosite_info_console

            echo
            echo -e "  Удаление всех баз GeoSite ${green}выполнено${reset}"
        ;;


        -remove)    # Полная деинсталляция XKeen
            smart_clear
            choice_for_remove="XKeen полностью со всеми зависимостями"
            choice_remove

            info_cron
            smart_clear
            echo
            echo -e "  Удаление задачи автообновления баз ${yellow}GeoFile${reset}"
            delete_cron_geofile
            logs_delete_cron_geofile_info_console

            echo
            echo -e "  Удаление задачи автообновления баз GeoFile ${green}выполнено${reset}"
            sleep 2

            # Удаление GeoSite's
            smart_clear
            echo
            echo -e "  Удаление всех баз ${yellow}GeoSite${reset}"

            delete_geosite_key
            logs_delete_geosite_info_console

            echo -e "  Удаление всех баз GeoSite ${green}выполнено${reset}"
            sleep 2

            # Удаление GeoIP's
            smart_clear
            echo
            echo -e "  Удаление всех баз ${yellow}GeoIP${reset}"

            delete_geoip_key
            logs_delete_geoip_info_console

            echo -e "  Удаление всех баз GeoIP ${green}выполнено${reset}"
            sleep 2

            # Удаление GeoIPSET
            smart_clear
            echo
            echo -e "  Удаление ${yellow}GeoIPSET${reset}"

            delete_geoipset_key
            logs_delete_geoipset_info_console

            echo -e "  Удаление GeoIPSET ${green}выполнено${reset}"
            sleep 2

            # Удаление файлов конфигурации Xray
            smart_clear
            echo
            echo -e "  Удаление ${yellow}конфигурационных файлов Xray${reset}"

            delete_configs
            logs_delete_configs_info_console

            echo
            echo -e "  Удаление конфигурационных файлов Xray ${green}выполнено${reset}"
            sleep 2

            # Удаление Xray
            smart_clear
            echo
            echo -e "  ${yellow}Удаление${reset} Xray"

            "$initd_file" stop >/dev/null 2>&1
            opkg remove xray_s
            rm -f "$install_dir/xray"
            rm -rf "/opt/etc/xray"

            echo
            echo -e "  Удаление Xray ${green}выполнено${reset}"
            sleep 2

            # Удаление Mihomo
            smart_clear
            echo
            echo -e "  ${yellow}Удаление${reset} Mihomo"
            opkg remove mihomo_s
            opkg remove yq_s
            rm -f "$install_dir/mihomo" "$install_dir/yq"
            rm -rf "$mihomo_conf_dir"

            echo
            echo -e "  Удаление Mihomo ${green}выполнено${reset}"
            sleep 2

            # Удаление XKeen
            smart_clear
            echo
            echo -e "  Удаление ${yellow}XKeen${reset}"
            opkg remove xkeen
            echo
            delete_tmp

            smart_clear
            delete_all

            smart_clear
            echo
            echo -e "  Полная деинсталляция ${yellow}XKeen${reset} и всех зависимостей ${green}выполнена${reset}"
            echo
            echo -e "  Установить ${yellow}XKeen${reset} заново можно командами:"
            echo
            echo -e "  ${green}opkg update && opkg install curl tar && cd /tmp${reset}"
            echo -e "  ${green}"'sh -c "$(curl -sSL https://raw.githubusercontent.com/jameszeroX/XKeen/main/install.sh)"'"${reset}"
        ;;


        -k)    # Переустановка XKeen
            test_connection
            check_health
            test_entware
            xkeen_set_info

            smart_clear
            echo
            echo -e "  Переустановка ${yellow}XKeen${reset}"

            choice_redownload_xkeen
            if [ -n "$redownload_xkeen" ]; then
                if [ "$xkeen_build" = "Stable" ]; then
                    download_func="download_xkeen"
                else
                    download_func="download_xkeen_dev"
                fi
                test_github
                sleep 2
                "$download_func"
            fi

            if ! install_xkeen; then
                echo
                echo -e "  Переустановка XKeen ${red}не выполнена${reset}"
                delete_tmp
                exit 1
            fi

            # Перезапуск скрипта
            grep -E "^\s*-k_post_install\s*\)" "$0" > /dev/null && exec sh "$0" -k_post_install
        ;;


        -k_post_install)
            . "$xkeen_dir/import.sh"
            init_directories
            xkeen_set_info
            new_features
            register_cron_initd
            migrate_ports_from_initd
            register_xkeen_initd
            create_xkeen_cfg
            choice_cancel_cron_select=true
            update_cron_geofile_task
            smart_clear
            echo

            echo -e "  Выполняется отмена регистрации предыдущей версии ${yellow}XKeen${reset}"
            delete_register_xkeen
            logs_delete_register_xkeen_info_console

            echo -e "  Выполняется регистрация новой версии ${yellow}XKeen${reset}"
            register_xkeen_list
            logs_register_xkeen_list_info_console

            register_xkeen_control
            logs_register_xkeen_control_info_console

            register_xkeen_status
            logs_register_xkeen_status_info_console

            if is_proxy_running; then
                "$initd_file" restart on >/dev/null 2>&1
            fi

            fixed_register_packages
            echo
            delete_tmp

            echo
            echo -e "  Переустановка XKeen ${green}выполнена${reset}"
            version_xkeen
        ;;


        -g)    # Переустановка баз GeoFile
            command -v xray >/dev/null 2>&1 || { echo -e "  ${red}Не обнаружено${reset} ядро проксирования Xray"; exit 1; }
            test_connection
            check_health
            test_github
            sleep 2

            geofile_update="true"

            smart_clear
            info_geosite
            info_geoip

            choice_geosite
            delete_geosite
            install_geosite
            sleep 2

            smart_clear
            choice_geoip
            delete_geoip
            install_geoip
            sleep 2

            echo -e "  Переустановка баз GeoFile ${green}выполнена${reset}"
        ;;


        -gips)    # Установка GeoIPSET
            test_connection
            check_health
            test_github

            smart_clear
            install_geoipset init
        ;;


        -dgips)    # Удаление GeoIPSET
            smart_clear
            delete_geoipset
        ;;


        -kb)    # Резервное копирование XKeen
            echo -e "  Создание резервной копии ${yellow}XKeen${reset}"
            manual_backup="on"
            backup_xkeen
        ;;


        -kbr)    # Восстановление XKeen из резервной копии
            echo -e "  Восстановление ${yellow}XKeen${reset} из резервной копии"
            restore_backup_xkeen
        ;;


        -xb)    # Резервное копирование конфигурации Xray
            command -v xray >/dev/null 2>&1 || { echo -e "  ${red}Не обнаружено${reset} ядро проксирования Xray"; exit 1; }
            echo -e "  Создание резервной копии ${yellow}конфигурации Xray${reset}"
            backup_configs_xray
        ;;


        -xbr)    # Восстановление конфигурации Xray из резервной копии
            command -v xray >/dev/null 2>&1 || { echo -e "  ${red}Не обнаружено${reset} ядро проксирования Xray"; exit 1; }
            echo -e "  Восстановление ${yellow}конфигурации Xray${reset} из резервной копии"
            restore_backup_configs_xray
        ;;


        -mb)    # Резервное копирование конфигурации Mihomo
            command -v mihomo >/dev/null 2>&1 || { echo -e "  ${red}Не обнаружено${reset} ядро проксирования Mihomo"; exit 1; }
            echo -e "  Создание резервной копии ${yellow}конфигурации Mihomo${reset}"
            backup_configs_mihomo
        ;;


        -mbr)    # Восстановление конфигурации Mihomo из резервной копии
            command -v mihomo >/dev/null 2>&1 || { echo -e "  ${red}Не обнаружено${reset} ядро проксирования Mihomo"; exit 1; }
            echo -e "  Восстановление ${yellow}конфигурации Mihomo${reset} из резервной копии"
            restore_backup_configs_mihomo
        ;;


        -tp)    # Показать прослушиваемые порты
            echo "  Определение прослушиваемых портов"
            tests_ports_client
        ;;


        -v|-version)    # Показать версию XKeen
            version_xkeen
        ;;


        -about)    # О программе
            smart_clear
            about_xkeen
        ;;


        -ad|-donate)    # Поддержать разработчиков
            smart_clear
            author_donate
        ;;


        -af|-feedback)    # Обратная связь
            smart_clear
            author_feedback
        ;;


        -h|-help)    # Помощь
            smart_clear
            help_xkeen
        ;;


        -start)    # Запуск XKeen
            add_chmod_init
            "$initd_file" start on
        ;;


        -stop)    # Остановка XKeen
            add_chmod_init
            "$initd_file" stop
        ;;


        -restart)    # Перезапуск XKeen
            add_chmod_init
            "$initd_file" restart on
        ;;


        -status)    # Состояние XKeen
            "$initd_file" status
        ;;


        -dscp)    # Состояние DSCP
            smart_clear
            "$initd_file" dscp
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            change_dscp_proxy "$action"

        ;;


        -auto)    # Смена режима запуска XKeen
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            smart_clear
            change_autostart_xkeen "$action"
            add_chmod_init
        ;;


        -startvb)    # Вывод информации при старте прокси-клиента
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            smart_clear
            change_start_verbose "$action"
            add_chmod_init
        ;;


        -fd)    # Смена режима контроля файловых дескрипторов
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            smart_clear
            change_file_descriptors "$action"
        ;;


        -cfd)    # Проверка количества открытых файловых дескрипторов
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            smart_clear
            check_file_descriptors
        ;;


        -ap)    # Добавить порт проксирования
            shift
            add_ports_donor "$@"
            shift $#
            sleep 2
            add_chmod_init
            if is_proxy_running; then
                "$initd_file" restart on >/dev/null 2>&1
            fi
        ;;


        -dp)    # Удалить порт проксирования
            shift
            del_ports_donor "$@"
            shift $#
            sleep 2
            add_chmod_init
            if is_proxy_running; then
                "$initd_file" restart on >/dev/null 2>&1
            fi
        ;;


        -cp)    # Получить список портов проксирования
            get_ports_donor
        ;;


        -ape)    # Добавить порт-исключение проксирования
            shift
            add_ports_exclude "$@"
            shift $#
            sleep 2
            add_chmod_init
            if is_proxy_running; then
                "$initd_file" restart on >/dev/null 2>&1
            fi
        ;;


        -dpe)    # Удалить порт-исключение проксирования
            shift
            del_ports_exclude "$@"
            shift $#
            sleep 2
            add_chmod_init
            if is_proxy_running; then
                "$initd_file" restart on >/dev/null 2>&1
            fi
        ;;


        -cpe)    # Получить список портов, исключёных из проксирования
            get_ports_exclude
        ;;


        -di)    # Время ожидания инициализации роутера
            shift
            delay_init "$1"
            add_chmod_init
        ;;


        -d)    # Время ожидания успешного запуска
            shift
            delay_autostart "$1"
            add_chmod_init
        ;;


        -diag)    # Диагностика XKeen
            location_entware_storage
            smart_clear
            diagnostic
        ;;


        -channel)    # Смена канала обновлений XKeen (Stable/Dev)
            smart_clear
            choice_channel_xkeen
            change_channel_xkeen
        ;;


        -xray)    # Смена ядра проксирования на Xray
            choice_xray_core
        ;;


        -mihomo)    # Смена ядра проксирования на Mihomo
            choice_mihomo_core
        ;;


        -ipv6)    # Включение/отключение IPv6 в KeeneticOS
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            smart_clear
            change_ipv6_support "$action"
        ;;


        -dns)    # Включение/отключение перенаправления DNS в прокси
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            smart_clear
            [ -n "$action" ] || warn_proxy_dns
            change_proxy_dns "$action"
        ;;


        -pr)    # Включение/отключение проксирования трафика Entware
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            smart_clear
            change_proxy_router "$action"
        ;;


        -pbr)    # Управление strict PBR-проверкой для исходящих подключений Xray/Mihomo
            case "$2" in
                on|off)
                    smart_clear
                    change_pbr_strict "$2"
                    shift
                    ;;
                status)
                    smart_clear
                    show_pbr_strict_status
                    shift
                    ;;
                codes)
                    smart_clear
                    show_pbr_policy_codes
                    shift
                    ;;
                *)
                    echo -e "  ${red}Ошибка${reset}: используйте ${yellow}xkeen -pbr on${reset}, ${yellow}off${reset}, ${yellow}status${reset} или ${yellow}codes${reset}"
                    exit 1
                    ;;
            esac
        ;;

        -killswitch)
            case "$2" in
                on|off)
                    smart_clear
                    change_killswitch "$2"
                    shift
                    ;;
                status)
                    smart_clear
                    show_killswitch_status
                    shift
                    ;;
                *)
                    echo -e "  ${red}Ошибка${reset}: используйте ${yellow}xkeen -killswitch on${reset}, ${yellow}off${reset} или ${yellow}status${reset}"
                    exit 1
                    ;;
            esac
        ;;


        -extmsg)    # Включение/отключение расширенных сообщений запуска XKeen
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            smart_clear
            change_extended_msg "$action"
        ;;


        -cbk)    # Включение/отключение резервного копирования XKeen при обновлении
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            smart_clear
            change_backup_xkeen "$action"
        ;;


        -aghfix)    # Включение/отключение исправления для AdGuard Home
            action=$(get_state_arg "$2")
            [ -n "$action" ] && shift
            smart_clear
            change_aghfix_xkeen "$action"
        ;;


        -xtest)    # Проверка конфигурации Xray
            core_conf_test xray
        ;;


        -mtest)    # Проверка конфигурации Mihomo
            core_conf_test mihomo
        ;;


        -health)    # Базовая проверка исправности Entware
            test_connection
            check_health
            echo -e "  Базовая проверка ${yellow}Entware${reset} выполнена. ${green}Система исправна${reset}"
        ;;


        -toff)    # Отключение таймаута при меделенной загрузке с GitHub
            :
        ;;


        -sb)    # Балансировка outbound по фактической скорости
            action=$(sb_command_arg "$2")
            [ -n "$action" ] && shift
            sb_control "$action" || exit 1
        ;;


        -sbt)    # Тик балансировки по скорости (вызывается cron, без интерактива)
            speed_balancer_settings
            [ "$sb_enabled" = "true" ] && sb_tick
        ;;


        *)
            echo -e "     Неизвестный ключ: ${red}$1${reset}"
            echo -e "     Список доступных ключей: ${yellow}xkeen -h${reset}"
        ;;
    esac
    shift
done
