#!/bin/bash
# ============================================
# КОНСТАНТЫ ДЛЯ НАСТРОЙКИ ОБНОВЛЕНИЯ
# ============================================
# Требуемое место для обновления (в ГБ)
MIN_ROOT_SPACE_FOR_INSTALL=4      # Минимальное место в корне для установки пакетов
MIN_SPACE_FOR_CACHE=3             # Минимальное место для кэша пакетов
# Вычисляем общее необходимое место
TOTAL_SPACE_NEEDED=$((MIN_ROOT_SPACE_FOR_INSTALL + MIN_SPACE_FOR_CACHE))
# Версия ROSA для обновления
TARGET_RELEASE="13"
CURRENT_RELEASE="2021.1"
# Пакеты, которые обновим отдельно (большие по размеру) - через запятую
BIG_PACKAGES="linux-firmware,chromium-browser-stable,firefox,firefox-ru,yandex-browser,newmoon,newmoon-ru"
OLD_PACKAGES="ffmpeg6 lesstif os-messages"
# Путь к файлу журнала
LOG_FILE="/var/log/update_platform.log"
# Флаг прерывания
INTERRUPTED=false
# ============================================
# КОНЕЦ КОНСТАНТ
# ============================================

# Функция для инициализации лог-файла
init_log() {
{
    echo "========================================================================"
    echo "Update log - $(date '+%Y-%m-%d %H:%M:%S')"
    echo "========================================================================"
    echo "Script: update-r12-to-r13.sh"
    echo "Target release: ROSA $TARGET_RELEASE"
    echo "Current release: $CURRENT_RELEASE"
    echo "System: $(uname -a)"
    echo ""
} > "$LOG_FILE"
}

# Определяем язык на основе локали
if [[ $LANG == ru* ]]; then
    LANGUAGE="ru"
else
    LANGUAGE="en"
fi

# Функции для локализованного вывода
msg() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local log_message="[$timestamp] $2"
    # Запись в лог
    echo "$log_message" >> "$LOG_FILE"
    # Вывод на экран
    if [[ $LANGUAGE == "en" ]]; then
        echo "$1"
    else
        echo "$2"
    fi
}

msg_error() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local log_message="[$timestamp] ERROR: $2"
    # Запись в лог
    echo "$log_message" >> "$LOG_FILE"
    # Вывод на экран
    if [[ $LANGUAGE == "en" ]]; then
        echo "ERROR: $1" >&2
    else
        echo "ОШИБКА: $2" >&2
    fi
}

# Функция для проверки наличия пакетов ROSA 13 в кэше
check_rosa13_packages_in_cache() {
    local cache_dir
    # Определяем реальное расположение кэша
    if [[ -L "/var/cache/dnf" ]]; then
        # Если это симлинк, получаем целевую директорию
        cache_dir=$(readlink -f "/var/cache/dnf")
    else
        # Иначе используем стандартный путь
        cache_dir="/var/cache/dnf"
    fi
    # Проверяем, существует ли директория кэша
    if [[ ! -d "$cache_dir" ]]; then
        return 1
    fi
    # Проверяем наличие файлов пакетов ROSA 13
    if find "$cache_dir" -name "*rosa13*" -type f 2>/dev/null | head -1 | grep -q .; then
        return 0  # Найдены пакеты ROSA 13
    else
        return 1  # Пакеты ROSA 13 не найдены
    fi
}

# Функция для очистки кэша DNF
clean_dnf_cache() {
msg "Cleaning DNF cache..." "Очищаем кэш DNF..."
    # Выполняем очистку кэша DNF
    if dnf clean all; then
        msg "DNF cache cleaned successfully." "Кэш DNF успешно очищен."
    return 0
    else
        msg_error "Failed to clean DNF cache." "Не удалось очистить кэш DNF."
    return 1
    fi
}

# Проверяем, не перенесен ли уже кэш DNF
check_dnf_cache_location() {
    if [[ -L "/var/cache/dnf" && "$(readlink /var/cache/dnf)" == "/home/dnf_cache" && -d "/home/dnf_cache" ]]; then
        return 0  # Кэш уже перенесен
    else
        return 1  # Кэш не перенесен или перенесен некорректно
    fi
}

# Функция для перемещения кэша DNF в /home
move_dnf_cache() {
    msg "Moving DNF cache to /home to free up space..." "Перемещаем кэш DNF в /home для освобождения места..."
    # Создаем новую директорию для кэша
    new_cache_dir="/home/dnf_cache"
    mkdir -p "$new_cache_dir"
    # Создаем структуру директорий
    mkdir -p "$new_cache_dir"/{packages,metadata}
    # Удаляем старый кэш (он пустой после очистки)
    if [[ -d "/var/cache/dnf" ]]; then
        rm -rf /var/cache/dnf
    fi
    # Создаем симлинк
    ln -sf "$new_cache_dir" /var/cache/dnf
    # Проверяем, что новый кэш работает
    if [[ -L "/var/cache/dnf" && "$(readlink /var/cache/dnf)" == "$new_cache_dir" && -d "$new_cache_dir" ]]; then
        msg "New DNF cache configured successfully in $new_cache_dir" "Новый кэш DNF успешно настроен в $new_cache_dir"
        return 0
    else
        msg_error "Failed to configure new DNF cache." "Не удалось настроить новый кэш DNF."
    return 1
    fi
}

# Функция для возврата кэша DNF на корневой раздел
restore_dnf_cache() {
    msg "Returning DNF cache to root partition..." "Возвращаем кэш DNF на корневой раздел..."
    # Удаляем симлинк
    rm -f /var/cache/dnf
    # Восстанавливаем оригинальную директорию
    mkdir -p /var/cache/dnf
    # Если в /home есть данные кэша, копируем их
    if [[ -d "/home/dnf_cache" && "$(ls -A /home/dnf_cache)" ]]; then
        msg "Moving cache back to root partition..." "Перемещаем кэш обратно на корневой раздел..."
        mv "/home/dnf_cache"/* /var/cache/dnf/ 2>/dev/null || true
    fi
    # Удаляем временную директорию в /home
    rm -rf "/home/dnf_cache"
    msg "DNF cache successfully returned to root partition." "Кэш DNF успешно возвращен на корневой раздел."
}

# Функция для обработки Ctrl+C
handle_interrupt() {
    INTERRUPTED=true
    echo
    msg "Update interrupted by user (Ctrl+C)." "Обновление прервано пользователем (Ctrl+C)."
    # Завершаем с кодом 130 (стандартный для SIGINT)
    exit 130
}

# Функция для поиска битых симлинков и их восстановления из кэша через rpm
fix_broken_symlinks_from_cache() {
    msg "Checking for broken symlinks and fixing via RPM cache..." "Проверка битых симлинков и исправление через кэш RPM..."

    local cache_dir
    # Определяем реальное расположение кэша (учитываем возможный перенос в /home)
    if [[ -L "/var/cache/dnf" ]]; then
        cache_dir=$(readlink -f "/var/cache/dnf")
    else
        cache_dir="/var/cache/dnf"
    fi

    if [[ ! -d "$cache_dir" ]]; then
        msg_error "Cache directory not found at $cache_dir" "Директория кэша не найдена по пути $cache_dir"
        return 1
    fi

    # 1. Находим битые симлинки и определяем пакеты
    local tmp_pkg_list="/tmp/broken_pkgs_update.txt"
    > "$tmp_pkg_list"

    find /usr/lib64 /usr/lib -xtype l 2>/dev/null | while read -r link; do
        rpm -qf --qf '%{NAME}\n' "$link" 2>/dev/null
    done | sort -u > "$tmp_pkg_list"

    local pkg_list
    pkg_list=$(cat "$tmp_pkg_list")
    rm -f "$tmp_pkg_list"

    if [ -z "$pkg_list" ]; then
        msg "No broken symlinks found in system libraries." "Битые симлинки в системных библиотеках не найдены."
        return 0
    fi

    # Выводим список на экран и в лог
    msg "Found broken symlinks in the following packages:" "Найдены битые симлинки в следующих пакетах:"
    echo "$pkg_list" | while read -r line; do
        echo "  - $line"
        echo "  - $line" >> "$LOG_FILE"
    done

    # 2. Ищем соответствующие RPM в кэше
    local rpms_to_fix=()
    while read -r pkg; do
        # Ищем самый свежий RPM для этого пакета в кэше
        local found_rpm
        found_rpm=$(find "$cache_dir" -type f -name "${pkg}-[0-9]*.rpm" 2>/dev/null | sort -V | tail -n 1)

        if [ -n "$found_rpm" ]; then
            rpms_to_fix+=("$found_rpm")
        else
            msg_error "RPM not found in cache for package: $pkg" "Не найден RPM в кэше для пакета: $pkg"
        fi
    done <<< "$pkg_list"

    # 3. Принудительная переустановка
    if [ ${#rpms_to_fix[@]} -gt 0 ]; then
        msg "Reinstalling ${#rpms_to_fix[@]} packages to fix symlinks..." "Переустановка ${#rpms_to_fix[@]} пакетов для исправления симлинков..."

        # --replacepkgs: ставим заново
        # --replacefiles: игнорируем конфликты файлов (важно при смене платформы)
        if rpm -Uvh --replacepkgs --replacefiles "${rpms_to_fix[@]}" >> "$LOG_FILE" 2>&1; then
            msg "Symlinks fixed successfully. Running ldconfig..." "Симлинки успешно исправлены. Запуск ldconfig..."
            ldconfig
        else
            msg_error "Failed to fix some packages via RPM. You may need to use --nodeps manually." "Не удалось исправить некоторые пакеты через RPM. Возможно, потребуется ручной запуск с --nodeps."
        fi
    fi
}

# Функция для проверки доступа к репозиториям
check_repositories_access() {
    msg "Checking access to repositories..." "Проверка доступа к репозиториям..."

    # Пытаемся обновить метаданные. Если репозитории недоступны, dnf вернет ошибку.
    if dnf makecache --refresh -y >> "$LOG_FILE" 2>&1; then
        msg "Repositories are accessible." "Репозитории доступны."
        return 0
    else
        msg_error "Failed to access repositories." "Не удалось получить доступ к репозиториям."
        echo ""
        if [[ $LANGUAGE == "ru" ]]; then
            echo "Возможные причины:"
            echo "1. Отсутствует подключение к интернету."
            echo "2. Неверные настройки прокси-сервера."
            echo "3. Истек срок действия ключа доступа или сертификата."
            echo "4. Репозитории временно недоступны."
            echo ""
            echo "Пожалуйста, проверьте соединение и повторите попытку."
        else
            echo "Possible reasons:"
            echo "1. No internet connection."
            echo "2. Incorrect proxy settings."
            echo "3. Expired access key or certificate."
            echo "4. Repositories are temporarily unavailable."
            echo ""
            echo "Please check your connection and try again."
        fi
        return 1
    fi
}

# Функция для проверки полного обновления системы перед переходом на новую платформу
check_system_fully_updated() {
    msg "Checking if current system is fully updated..." "Проверка полного обновления текущей системы..."

    # 1. Попытка синхронизации метаданных и проверки целостности
    # DNF сам попытается завершить прерванные транзакции при обновлении кэша
    msg "Verifying package manager consistency..." "Проверка согласованности менеджера пакетов..."
    if ! dnf makecache --refresh -y >> "$LOG_FILE" 2>&1; then
         msg_error "Failed to refresh repository metadata." "Не удалось обновить метаданные репозиториев."
         return 1
    fi

    # 2. Проверка наличия доступных обновлений для текущей платформы
    local updates_available
    updates_available=$(dnf check-update -q 2>/dev/null)
    local dnf_rc=$?

    # Код возврата 100 означает, что есть обновления. Код 0 — всё обновлено.
    # Любой другой код (например, 1) — ошибка выполнения команды.
    if [ $dnf_rc -eq 1 ]; then
         msg_error "Failed to check for updates (DNF error)." "Не удалось проверить наличие обновлений (ошибка DNF)."
         return 1
    fi

    if [ -n "$updates_available" ]; then
        msg_error "System is not fully updated." "Система обновлена не полностью."
        if [[ $LANGUAGE == "ru" ]]; then
            echo "Обнаружены доступные обновления для текущей платформы ($CURRENT_RELEASE)."
            echo "Пожалуйста, выполните:"
            echo "  sudo dnf update"
            echo "  sudo reboot"
            echo "И только после этого запускайте скрипт обновления платформы."
        else
            echo "Updates are available for the current platform ($CURRENT_RELEASE)."
            echo "Please run:"
            echo "  sudo dnf update"
            echo "  sudo reboot"
            echo "And only then run the platform update script."
        fi
        return 1
    fi

    msg "System is fully up-to-date and consistent." "Система полностью обновлена и согласована."
    return 0
}

# Функция для выполнения обновления системы в три этапа
perform_system_update() {
    # Этап 1: Скачивание ВСЕХ пакетов, включая большие (сохраняем в кэше)
    if [[ $INTERRUPTED == true ]]; then return 1; fi
    msg "Stage 1: Downloading packages..." "Этап 1: Скачивание пакетов..."
    if dnf distrosync --releasever=$TARGET_RELEASE --downloadonly --allowerasing -y --setopt=keepcache=True; then
        msg "All packages downloaded successfully and kept in cache." "Все пакеты успешно скачаны и сохранены в кэше."
    else
        msg_error "Failed to download packages." "Не удалось скачать пакеты."
        return 1
    fi
    echo

    # Этап 2: Обновление без больших пакетов
    if [[ $INTERRUPTED == true ]]; then return 1; fi
    msg "Stage 2: Updating without large packages..." "Этап 2: Обновление без больших пакетов..."
    if dnf distrosync --releasever=$TARGET_RELEASE --exclude="$BIG_PACKAGES" --allowerasing -y --setopt=keepcache=True; then
        msg "System updated (without large packages) successfully." "Система обновлена (без больших пакетов) успешно."

        # === ВСТАВКА: Проверка и фикс битых симлинков ===
        fix_broken_symlinks_from_cache
        # ================================================
    else
        msg_error "Failed to update system (without large packages)." "Не удалось обновить систему (без больших пакетов)."
        return 1
    fi
    echo

    # Этап 3: Обновление оставшихся больших пакетов
    if [[ $INTERRUPTED == true ]]; then return 1; fi
    msg "Stage 3: Updating remaining large packages..." "Этап 3: Обновление оставшихся больших пакетов..."
    if dnf distrosync --releasever=$TARGET_RELEASE --allowerasing -y; then
        msg "All packages updated successfully." "Все пакеты успешно обновлены."
    else
        msg_error "Failed to update remaining packages." "Не удалось обновить оставшиеся пакеты."
        return 1
    fi
    echo

    if [[ $INTERRUPTED == true ]]; then return 1; fi
    # Выполняем переустановку загрузчика
    msg "Reinstalling bootloader..." "Выполняем переустановку загрузчика..."
    if grub2-install-hooks; then
        msg "Bootloader updated successfully." "Загрузчик успешно обновлен."
    else
        msg_error "Failed to update bootloader." "Не удалось обновить загрузчика."
        return 1
    fi
    echo

    if [[ $INTERRUPTED == true ]]; then return 1; fi
    # Удаляем осиротевшие пакеты и известные пакеты от старой платформы
    msg "Removing orphaned packages with autoremove..." "Удаляем осиротевшие пакеты с помощью autoremove..."
    if dnf autoremove -y; then
        msg "Autoremove completed successfully." "Autoremove успешно завершен."
        if dnf erase $OLD_PACKAGES -y; then
            msg "Remove old packages successfully." "Удаление устаревших пакетов успешно завершено."
        else
            msg "Remove old packages failed." "Удаление устаревших пакетов завершилось с ошибкой."
        fi
    else
        msg_error "Autoremove failed, but continuing." "Autoremove завершился с ошибкой, но продолжаем."
    fi
    echo

    # Проверяем наличие пакетов от старой версии
    msg "Checking for packages from previous platorm..." "Проверяем наличие пакетов от предыдущей платформы..."
    local old_packages
    old_packages=$(rpm -qa --qf '%{name} %{sourcerpm} %{disttag}
' | grep $CURRENT_RELEASE)
    if [[ -n "$old_packages" ]]; then
        msg "Found packages from previous platform:" "Найдены пакеты от предыдущей платформы:"
        {
            echo ""
            echo "Packages from previous platform:"
            echo "--------------------------------------------"
            echo "$old_packages"
            echo "--------------------------------------------"
        } >> "$LOG_FILE"
        # Краткое сообщение на экран
        echo "$old_packages" | head -5
        if [[ $(echo "$old_packages" | wc -l) -gt 5 ]]; then
            msg "... and more $(($(echo "$old_packages" | wc -l) - 5)) packages. See $LOG_FILE for details." "... и еще $(($(echo "$old_packages" | wc -l) - 5)) пакетов. Подробности см. в $LOG_FILE."
        fi
    else
        msg "No packages from previous platform found." "Пакетов от предыдущей платформы не найдено."
    fi
    return 0
}

cleanup_system_before_update() {
    msg "Starting system cleanup to free up space..." "Начинаем очистку системы для освобождения места..."
    # 1. Сжатие журналов (оставляем записи за последние 3 дня)
    msg "Compressing system journals (keeping last 2 days)..." "Сжимаем системные журналы (оставляем последние 2 дня)..."
    if journalctl --vacuum-time=2d 2>/dev/null; then
        msg "System journals compressed successfully." "Системные журналы успешно сжаты."
    else
        msg_error "Failed to compress journals (journalctl not available?)." "Не удалось сжать журналы (journalctl недоступен?)."
    fi
    # 2. Удаление старых ядер (оставляем 2 последние версии)
    msg "Removing old kernels..." "Удаляем старые ядра..."
    if dnf remove --oldinstallonly --setopt installonly_limit=0 -y 2>/dev/null; then
        msg "Old kernels removed successfully." "Старые ядра успешно удалены."
    else
        msg "No old kernels found or error occurred." "Старые ядра не найдены или произошла ошибка."
    fi
    # 3. Удаление неиспользуемых зависимостей
    msg "Removing unused dependencies..." "Удаляем неиспользуемые зависимости..."
    if dnf autoremove -y 2>/dev/null; then
        msg "Unused dependencies removed." "Неиспользуемые зависимости удалены."
    fi
    # 4. Очистка кэша пакетов
    if ! check_rosa13_packages_in_cache; then
        clean_dnf_cache
    fi
    msg "System cleanup completed." "Очистка системы завершена."
    echo
}

wait_before_exit() {
    rm -f /usr/share/xsessions/update-r12-to-r13.desktop
    echo
    msg "PLATFORM UPDATE COMPLETED" "ОБНОВЛЕНИЕ ПЛАТФОРМЫ ЗАВЕРШЕНО"
    echo "============================================================================"
    msg "Press any key " "Нажмите любую клавишу"
    read -n 1 -s -t 600
    reboot
}

#**************************************************************Начало основного кода скрипта **************************************************************************************************************
# Вывод предупреждения о обновлении
echo "========================================================================"
if [[ $LANGUAGE == "ru" ]]; then
    echo "Этот скрипт выполнит обновление системы РОСА Линукс с платформы $CURRENT_RELEASE на платформу РОСА $TARGET_RELEASE."
    echo "Перед обновлением рекомендуется:"
    echo "1. Сделать резервное копирование пользовательских данных"
    echo "2. Создать загрузочный носитель с релизом РОСА $TARGET_RELEASE для ручного обновления или релизом РОСА 12 для отката при невозможности обновления"
    echo ""
    echo "Требования к месту:"
    echo "- Корневой раздел: $MIN_ROOT_SPACE_FOR_INSTALL ГБ для установки"
    echo "- Кэш пакетов: $MIN_SPACE_FOR_CACHE ГБ для кэша пакетов"
    echo "- Всего при кэше в корне: $TOTAL_SPACE_NEEDED ГБ в корневом разделе"
else
    echo "This script will update ROSA Linux from platform $CURRENT_RELEASE to ROSA $TARGET_RELEASE."
    echo "Before updating, it is recommended to:"
    echo "1. Backup your user data"
    echo "2. Create bootable media with ROSA $TARGET_RELEASE release for manual update or ROSA 12 release for rollback if update fails"
    echo ""
    echo "Space requirements:"
    echo "- Root partition: $MIN_ROOT_SPACE_FOR_INSTALL GB for installation"
    echo "- Cache space: $MIN_SPACE_FOR_CACHE GB for package cache"
    echo "- Total needed if cache stays in root: $TOTAL_SPACE_NEEDED GB in root"
fi
echo "========================================================================"

# Запрос подтверждения с использованием printf
if [[ $LANGUAGE == "ru" ]]; then
    printf "Продолжить? [Да/Нет] (y/N) (по умолчанию: Нет): "
else
    printf "Continue? [Yes/No] (default: No): "
fi
read -r confirm
# Обработка ответа (регистронезависимая)
shopt -s nocasematch
if [[ ! $confirm =~ ^(yes|да|y|д)$ ]]; then
    if [[ $LANGUAGE == "ru" ]]; then
        echo "Обновление отменено пользователем."
    else
        echo "Update cancelled by user."
    fi
    exit 0
fi
shopt -u nocasematch
echo

# Проверяем, что скрипт запущен от root
if [[ $EUID -ne 0 ]]; then
    msg_error "This script must be run as root" "Этот скрипт должен быть запущен с правами root"
    exit 1
fi

init_log
trap handle_interrupt SIGINT
msg "Starting platform update script..." "Начало выполнения скрипта обновления платформы..."
msg "Press Ctrl+C to cancel at any time." "Нажмите Ctrl+C для отмены в любой момент."
echo "================================================================================"

# ПРОВЕРКА ПОЛНОГО ОБНОВЛЕНИЯ СИСТЕМЫ
if ! check_system_fully_updated; then
    exit 1
fi
echo "================================================================================"

if [[ $LANGUAGE == "ru" ]]; then
    echo "ОЧИСТКА СИСТЕМЫ ПЕРЕД ОБНОВЛЕНИЕМ"
    echo "================================================================================"
    echo "Будет освобождено место в корневом разделе за счет удаления ненужных файлов:"
    echo ""
    echo "1. СЖАТИЕ СИСТЕМНЫХ ЛОГОВ:"
    echo "   - Сохраняются только журналы (journald) за последние 2 дня"
    echo "   - Старые файлы логов будут удалены, освободит ~100-500 МБ"
    echo ""
    echo "2. УДАЛЕНИЕ СТАРЫХ ЯДЕР:"
    echo "   - Остается только последняя версия ядра"
    echo "   - Будут удалены старые пакеты ядер и модули, освободит ~500-1500 МБ"
    echo "   - Текущее ядро всегда остается"
    echo ""
    echo "3. ОЧИСТКА КЭША ПАКЕТОВ:"
    echo "   - Удаляет скачанные .rpm файлы из кэша DNF"
    echo "   - Освободит ~200-1000 МБ (если пакеты ROSA 13 еще не скачаны)"
    echo ""
    echo "4. УДАЛЕНИЕ НЕИСПОЛЬЗУЕМЫХ ЗАВИСИМОСТЕЙ:"
    echo "   - Удаляет осиротевшие пакеты, больше не нужные установленному ПО"
    echo ""
    echo "Ожидаемый итоговый объем: 800 МБ - 3 ГБ"
    echo "================================================================================"
    printf "Выполнить очистку системы? [Да/Нет] (Y/n) (по умолчанию: Да): "
else
    echo "SYSTEM CLEANUP BEFORE UPDATE"
    echo "================================================================================"
    echo "This will free up space in the root partition by removing unnecessary files:"
    echo ""
    echo "1. COMPRESS SYSTEM LOGS:"
    echo "   - Keeps only the last 2 days of system journal (journald) logs"
    echo "   - Old log files will be deleted, freeing ~100-500 MB"
    echo ""
    echo "2. REMOVE OLD KERNELS:"
    echo "   - Keeps only latest kernel"
    echo "   - Old kernel packages and modules will be removed, freeing ~500-1500 MB"
    echo "   - At least one working kernel will always remain"
    echo ""
    echo "3. CLEAN PACKAGE CACHE:"
    echo "   - Removes downloaded .rpm files from DNF cache"
    echo "   - Frees ~200-1000 MB (unless ROSA 13 packages are already downloaded)"
    echo ""
    echo "4. REMOVE UNUSED DEPENDENCIES:"
    echo "   - Removes orphaned packages no longer needed by any installed software"
    echo ""
    echo "Total expected space freed: 800 MB - 3 GB"
    echo "================================================================================"
    printf "Continue? [Yes/No] (default: Yes): "
fi
read -r cleanup_confirm
# Обработка ответа
shopt -s nocasematch
if [[ ! $cleanup_confirm =~ ^(no|нет|n|н)$ ]]; then
    cleanup_system_before_update
fi
shopt -u nocasematch

# ПРОВЕРКА ДОСТУПА К РЕПОЗИТОРИЯМ (если пакеты еще не в кэше)
if ! check_rosa13_packages_in_cache; then
    if ! check_repositories_access; then
        exit 1
    fi
fi

if check_rosa13_packages_in_cache; then
    # Если в кэше уже есть пакеты ROSA 13, значит обновление уже начиналось
    msg "Found ROSA $TARGET_RELEASE packages in cache, skipping space check and cache cleanup" "Найдены пакеты ROSA $TARGET_RELEASE в кэше, пропускаем проверку места и очистку кэша"
    # Выполняем обновление системы
    if perform_system_update; then
        # Если кэш был перемещен, возвращаем его
        if check_dnf_cache_location; then
            restore_dnf_cache
        fi
        wait_before_exit
        exit 0
    else
        exit 1
    fi
else
    # Проверяем доступное место в корневом разделе и /home
    root_space=$(df / --output=avail | tail -1)
    home_space=$(df /home --output=avail 2>/dev/null | tail -1)
    # Конвертируем в ГБ (1 ГБ = 1048576 КБ)
    root_gb=$((root_space / 1048576))
    # Если /home существует, получаем свободное место, иначе считаем 0
    if [[ -n "$home_space" ]]; then
        home_gb=$((home_space / 1048576))
    else
        home_gb=0
    fi
    msg "Free in root: $root_gb GB" "Свободно в корне: $root_gb ГБ"
    if [[ $home_gb -gt 0 ]]; then
        msg "Free in /home: $home_gb GB" "Свободно в /home: $home_gb ГБ"
    fi

    # Проверяем условия для выполнения обновления
    # Проверяем, находятся ли корень и /home на одном разделе
    root_device=$(df / --output=source | tail -1)
    if [[ -d "/home" ]]; then
        home_device=$(df /home --output=source 2>/dev/null | tail -1)
    else
        home_device=""
    fi

    # Если /home не существует или корень и /home на одном разделе
    if [[ -z "$home_device" ]] || [[ "$root_device" == "$home_device" ]]; then
        # Если /home нет или они на одном разделе, нужно TOTAL_SPACE_NEEDED ГБ в корне
        if [[ $root_gb -ge $TOTAL_SPACE_NEEDED ]]; then
            msg "Enough space in root partition. Starting system update..." "Достаточно места в корневом разделе. Запускаем обновление системы..."
            # Выполняем обновление системы
            if perform_system_update; then
                wait_before_exit
                exit 0
            else
                exit 1
            fi
        else
            msg_error "Not enough space for system update." "Недостаточно места для обновления системы."
            if [[ $LANGUAGE == "en" ]]; then
                echo "Need $TOTAL_SPACE_NEEDED GB free in root partition."
                echo "Current: root has $root_gb GB"
                echo ""
                echo "/home is on the same partition or doesn't exist, cannot move cache to save space."
            else
                echo "Нужно $TOTAL_SPACE_NEEDED ГБ свободно в корневом разделе."
                echo "Сейчас: в корне $root_gb ГБ"
                echo ""
                echo "/home находится на том же разделе или отсутствует, невозможно переместить кэш для экономии места."
            fi
            exit 1
        fi
    else
        # Если корень и /home на разных разделах
        if [[ $root_gb -ge $TOTAL_SPACE_NEEDED ]]; then
            msg "Enough space in root partition. Starting system update..." "Достаточно места в корневом разделе. Запускаем обновление системы..."
            # Выполняем обновление системы
            if perform_system_update; then
                wait_before_exit
                exit 0
              else
                exit 1
            fi
        elif [[ $root_gb -ge $MIN_ROOT_SPACE_FOR_INSTALL && $home_gb -ge $MIN_SPACE_FOR_CACHE ]]; then
            msg "Not enough space in root, moving cache to /home..." "Недостаточно места в корне, перемещаем кэш в /home..."
            # Перемещаем кэш DNF
            if move_dnf_cache; then
                # Выполняем обновление системы
                if perform_system_update; then
                    restore_dnf_cache
                    wait_before_exit
                    exit 0
                else
                    # В случае ошибки обновления, возвращаем кэш
                    restore_dnf_cache
                    exit 1
                fi
            else
                exit 1
            fi
        else
            msg_error "Not enough space for system update." "Недостаточно места для обновления системы."
            if [[ $LANGUAGE == "en" ]]; then
                echo "Need either:"
                echo "  - $TOTAL_SPACE_NEEDED GB free in root partition (if cache stays in root), OR"
                echo "  - $MIN_ROOT_SPACE_FOR_INSTALL GB free in root and $MIN_SPACE_FOR_CACHE GB free in /home (to move cache to /home)"
                echo "Current: root has $root_gb GB, /home has $home_gb GB"
            else
                echo "Нужно либо:"
                echo "  - $TOTAL_SPACE_NEEDED ГБ свободно в корневом разделе (если кэш остается в корне), ИЛИ"
                echo "  - $MIN_ROOT_SPACE_FOR_INSTALL ГБ свободно в корне и $MIN_SPACE_FOR_CACHE ГБ свободно в /home (чтобы переместить кэш в /home)"
                echo "Сейчас: в корне $root_gb ГБ, в /home $home_gb ГБ"
            fi
            exit 1
        fi
    fi
fi
