#!/usr/bin/env bash
stty erase ^? 2>/dev/null || true
stty erase ^H 2>/dev/null || true

set -euo pipefail
# Linux 软件包更新 + 清理

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

DIST_CHOICE_SET=0
DO_CLEAN=1
DO_AUTO_UPDATE=1
DO_DIST_UPGRADE=0
MIN_FREE_MB=512
HOLDS_CHOICE=unhold
REHOLD_CHOICE=rehold
UNHELD_BY_SCRIPT=0
PRO_MARKER="/var/lib/up-sh/pro-auto-attach"
PRO_DETACH_MARKER="/var/lib/up-sh/pro-auto-detached"
DO_PRO_AUTO_ATTACH=1
DO_PRO_AUTO_DETACH=1
LOG_FILE="/var/log/up-sh.log"

SERVICES_TO_RESTART=(xray)

usage() {
    cat <<'EOF'
Linux 软件包更新 + 清理

用法: up.sh [选项]

  （无参数）          询问是否升大版本（默认 n），然后执行软件包更新
  y, -y, --yes        升大版本 + 更新（跳过询问）
  n, -n, --no         不升版本，仅更新补丁（跳过询问，日常推荐）
  --clean             更新后清理（默认开启）
  --no-clean          跳过清理
  --auto-update       启用自动安全更新（默认开启）
  --no-auto-update    跳过自动安全更新
  --dist-upgrade      同 -y，升大版本
  --min-free MB       最低剩余磁盘，默认 512MB
  --holds 模式        处理 apt-mark hold 的软件包：unhold 自动解除并升级（默认）/ skip 跳过
  --rehold            升级后恢复被解除的 hold 状态（默认）
  --no-rehold         升级后不恢复 hold（保持可升级）
  --no-pro            不自动绑定/解绑 Ubuntu Pro（默认自动）
  -h, --help          显示帮助

开局询问（仅 bash up.sh 无参数时）:
  y = 执行版本升级    n = 跳过版本升级，仅更新组件（默认）

Ubuntu Pro 自动流程（仅 Ubuntu）:
  1. 检测到未绑定且未解绑过 -> 自动执行 pro attach，等你浏览器完成登录后继续
  2. 更新完成（必要时手动重启）后再运行一次 up.sh
     -> 检查系统无残留问题后自动 pro detach（释放免费名额）

示例:
  bash up.sh           # 询问后更新；回车或 n 跳过升版本
  bash up.sh           # 快捷命令可发两行：bash up.sh + n
  bash up.sh n         # 跳过询问，只更新
  bash up.sh y         # 跳过询问，升版本 + 更新
EOF
}

while [[ $# -gt 0 ]]; do
    case "$1" in
        y|Y|-y|--yes|--dist-upgrade)
            DIST_CHOICE_SET=1
            DO_DIST_UPGRADE=1
            ;;
        n|N|-n|--no)
            DIST_CHOICE_SET=1
            DO_DIST_UPGRADE=0
            ;;
        --clean) DO_CLEAN=1 ;;
        --no-clean) DO_CLEAN=0 ;;
        --auto-update) DO_AUTO_UPDATE=1 ;;
        --no-auto-update) DO_AUTO_UPDATE=0 ;;
        --min-free) MIN_FREE_MB="${2:?缺少 MB 数值}"; shift ;;
        --holds) HOLDS_CHOICE="${2:?缺少参数(unhold/skip)}"; shift ;;
        --rehold) REHOLD_CHOICE=rehold ;;
        --no-rehold) REHOLD_CHOICE=no-rehold ;;
        --no-pro) DO_PRO_AUTO_ATTACH=0; DO_PRO_AUTO_DETACH=0 ;;
        -h|--help) usage; exit 0 ;;
        *) echo "未知参数: $1"; usage; exit 1 ;;
    esac
    shift
done

log() {
    local msg="$*"
    echo -e "$msg" | tee -a "$LOG_FILE"
}

require_root() {
    if [[ "$(id -u)" -ne 0 ]]; then
        echo -e "${RED}错误：请使用 root 或 sudo 运行${NC}"
        exit 1
    fi
}

# 开局唯一交互（原脚本设计）：是否升大版本，默认 n；之后始终执行同版本更新
ask_version_upgrade() {
    if [[ "$DIST_CHOICE_SET" -eq 1 ]]; then
        return 0
    fi
    printf '\n\033[0;32m%s\033[0m' "是否需要执行版本升级（如Ubuntu 20.04→22.04、CentOS 7→8）？[y/N] "
    read -r -n 1 || true
    echo -e "\n"
    if [[ "${REPLY:-n}" =~ ^[Yy]$ ]]; then
        DO_DIST_UPGRADE=1
    else
        DO_DIST_UPGRADE=0
    fi
}

# 仅 apt 系：列出被 apt-mark hold 的软件包
detect_held_packages() {
    HELD_PKGS=""
    [[ "$PKG_MANAGER" != "apt" ]] && return 0
    HELD_PKGS=$(apt-mark showhold 2>/dev/null | tr '\n' ' ' | sed 's/ *$//')
}

# 仅 apt 系：升级前自动临时解除 hold，避免 apt-get upgrade 悄悄跳过
ask_holds() {
    [[ "$PKG_MANAGER" != "apt" ]] && return 0
    [[ -z "$HELD_PKGS" ]] && return 0

    if [[ "$HOLDS_CHOICE" == "unhold" ]]; then
        log "${YELLOW}解除 hold：${HELD_PKGS}${NC}"
        apt-mark unhold $HELD_PKGS
        UNHELD_BY_SCRIPT=1
    else
        log "${YELLOW}跳过被 hold 的软件包：${HELD_PKGS}${NC}"
    fi
}

# 仅 apt 系：升级结束后自动恢复原先的 hold
ask_rehold() {
    [[ "$PKG_MANAGER" != "apt" ]] && return 0
    [[ "$UNHELD_BY_SCRIPT" -ne 1 ]] && return 0
    [[ -z "$HELD_PKGS" ]] && return 0

    if [[ "$REHOLD_CHOICE" == "rehold" ]]; then
        log "${YELLOW}恢复 hold：${HELD_PKGS}${NC}"
        apt-mark hold $HELD_PKGS
    else
        log "${GREEN}已解除 hold，保持可升级状态：${HELD_PKGS}${NC}"
    fi
}

is_ubuntu() {
    local id
    id=$(awk -F= '/^ID=/{print $2}' /etc/os-release 2>/dev/null | tr -d '"')
    [[ "$id" == "ubuntu" ]]
}

pro_attached() {
    pro status --format=json 2>/dev/null | grep -q '"attached": true'
}

# 仅 Ubuntu：检测到未绑定且未解绑过时，自动 pro attach（阻塞等待浏览器完成登录）
pro_ensure_attached() {
    [[ "$PKG_MANAGER" != "apt" ]] && return 0
    is_ubuntu || return 0
    command -v pro >/dev/null 2>&1 || return 0
    [[ "$DO_PRO_AUTO_ATTACH" -ne 1 ]] && return 0

    if pro_attached; then
        log "${GREEN}Ubuntu Pro 已绑定${NC}"
        return 0
    fi

    if [[ -f "$PRO_DETACH_MARKER" ]]; then
        log "${YELLOW}此前已通过 up.sh 解绑过 Ubuntu Pro，跳过自动绑定${NC}"
        log "${YELLOW}（如需再次自动绑定，请删除 ${PRO_DETACH_MARKER}）${NC}"
        return 0
    fi

    rm -f "$PRO_MARKER"
    log "${YELLOW}检测到 Ubuntu 系统且未绑定 Ubuntu Pro，开始自动绑定（免费个人版，最多 5 台）${NC}"
    echo -e "\n${BLUE}请在浏览器打开下方链接，输入授权码完成登录；${NC}"
    echo -e "${BLUE}绑定完成后脚本会自动继续执行更新${NC}\n"
    pro attach
    if pro_attached; then
        mkdir -p "$(dirname "$PRO_MARKER")"
        touch "$PRO_MARKER"
        log "${GREEN}Ubuntu Pro 绑定成功${NC}"
    else
        log "${YELLOW}Ubuntu Pro 绑定未完成，继续更新（本次无 ESM 补丁）${NC}"
    fi
}

# 仅 Ubuntu：检查系统已更新且无需重启后，自动 pro detach 释放免费名额
pro_auto_detach() {
    [[ "$PKG_MANAGER" != "apt" ]] && return 0
    is_ubuntu || return 0
    command -v pro >/dev/null 2>&1 || return 0
    [[ "$DO_PRO_AUTO_DETACH" -ne 1 ]] && return 0
    [[ -f "$PRO_MARKER" ]] || return 0

    if ! pro_attached; then
        rm -f "$PRO_MARKER"
        return 0
    fi

    local issues=0
    if apt-get -s upgrade 2>/dev/null | grep -q 'will be upgraded'; then
        log "${YELLOW}仍有待升级的软件包，暂不解绑 Ubuntu Pro${NC}"
        issues=1
    fi
    if needs_reboot; then
        log "${YELLOW}系统仍需重启，暂不解绑 Ubuntu Pro${NC}"
        issues=1
    fi
    if [[ "$issues" -ne 0 ]]; then
        log "${YELLOW}下次运行 up.sh 时将再次检查并自动解绑${NC}"
        return 0
    fi

    log "${GREEN}检查通过：系统已是最新且无需重启，自动解除 Ubuntu Pro 绑定（释放免费名额）${NC}"
    pro detach
    rm -f "$PRO_MARKER"
    touch "$PRO_DETACH_MARKER"
    log "${GREEN}Ubuntu Pro 已解绑${NC}"
}

# 禁用 debconf / needrestart / ucf 等一切交互（含 cloud.cfg 类 Y/N 提示）
setup_noninteractive() {
    export DEBIAN_FRONTEND=noninteractive
    export DEBCONF_NONINTERACTIVE_SEEN=true
    export DEBIAN_PRIORITY=critical
    export NEEDRESTART_MODE=a
    # UCF：cloud.cfg 等配置文件冲突，自动保留本地版（等同默认 N）
    export UCF_FORCE_CONFFOLD=1
    export UCF_FORCE_CONFFOLD=yes
    unset UCF_FORCE_CONFFNEW

    # apt/dpkg 全局非交互（比命令行 -o 更可靠，子进程也生效）
    mkdir -p /etc/apt/apt.conf.d
    cat >/etc/apt/apt.conf.d/99-up-sh-noninteractive <<'EOF'
APT {
  Get {
    Assume-Yes "true";
  };
};
Dpkg {
  Options {
    "--force-confdef";
    "--force-confold";
  };
  Use-Pty "false";
};
EOF

    # ucf 全局：冲突时保留已安装版本，不询问 Y/N/O
    if [[ -f /etc/ucf.conf ]]; then
        grep -q '^confold=' /etc/ucf.conf \
            && sed -i 's/^confold=.*/confold=yes/' /etc/ucf.conf \
            || echo 'confold=yes' >> /etc/ucf.conf
        grep -q '^confnew=' /etc/ucf.conf \
            && sed -i 's/^confnew=.*/confnew=no/' /etc/ucf.conf \
            || echo 'confnew=no' >> /etc/ucf.conf
    else
        cat >/etc/ucf.conf <<'EOF'
# Managed by up.sh — keep local config on conflicts
confold=yes
confnew=no
EOF
    fi

    mkdir -p /etc/needrestart/conf.d
    cat >/etc/needrestart/conf.d/50-up-sh-noninteractive.conf <<'EOF'
$nrconf{restart} = 'a';
$nrconf{kernelhints} = 0;
EOF

    if command -v debconf-set-selections &>/dev/null; then
        debconf-set-selections <<'EOF' 2>/dev/null || true
openssh-server openssh-server/permit-root-login select without-password
openssh-server openssh-server/password-authentication select true
unattended-upgrades unattended-upgrades/enable_auto_updates boolean true
EOF
    fi
}

preseed_unattended_upgrades() {
    command -v debconf-set-selections &>/dev/null || return 0
    echo 'unattended-upgrades unattended-upgrades/enable_auto_updates boolean true' \
        | debconf-set-selections
    mkdir -p /etc/apt/apt.conf.d
    cat >/etc/apt/apt.conf.d/20auto-upgrades <<'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::AutocleanInterval "0";
APT::Periodic::Unattended-Upgrade "1";
EOF
}

# apt 统一参数：保留本地已修改的配置（sshd_config / cloud.cfg 等）
apt_get() {
    env DEBIAN_FRONTEND=noninteractive \
        UCF_FORCE_CONFFOLD=yes \
        NEEDRESTART_MODE=a \
        apt-get \
        -o Dpkg::Options::=--force-confdef \
        -o Dpkg::Options::=--force-confold \
        -o DPkg::Lock::Timeout=120 \
        "$@"
}

dpkg_configure_all() {
    env DEBIAN_FRONTEND=noninteractive \
        UCF_FORCE_CONFFOLD=yes \
        NEEDRESTART_MODE=a \
        dpkg --force-confdef --force-confold --configure -a
}

detect_system() {
    setup_noninteractive

    if command -v apt-get &>/dev/null; then
        PKG_MANAGER="apt"
    elif command -v dnf &>/dev/null; then
        PKG_MANAGER="dnf"
    elif command -v yum &>/dev/null; then
        PKG_MANAGER="yum"
    elif command -v pacman &>/dev/null; then
        PKG_MANAGER="pacman"
    elif command -v zypper &>/dev/null; then
        PKG_MANAGER="zypper"
    else
        log "${RED}未检测到支持的包管理器（apt/dnf/yum/pacman/zypper）${NC}"
        exit 1
    fi
    log "${GREEN}包管理器：${PKG_MANAGER}${NC}"
}

check_disk_space() {
    local free_mb
    free_mb=$(df -Pm / | awk 'NR==2 {print $4}')
    if [[ "$free_mb" -lt "$MIN_FREE_MB" ]]; then
        log "${RED}磁盘空间不足：/ 剩余 ${free_mb}MB，至少需要 ${MIN_FREE_MB}MB${NC}"
        exit 1
    fi
    log "${GREEN}磁盘检查通过：/ 剩余 ${free_mb}MB${NC}"
}

run_step() {
    local title="$1"
    shift
    log "${GREEN}>>> ${title}${NC}"
    if "$@"; then
        log "${GREEN}完成：${title}${NC}"
    else
        log "${YELLOW}警告：${title} 未完全成功，继续后续步骤${NC}"
        return 0
    fi
}

update_index() {
    case "$PKG_MANAGER" in
        apt) apt_get update ;;
        dnf)
            set +e; dnf check-update; local rc=$?; set -e
            [[ "$rc" -eq 0 || "$rc" -eq 100 ]] || return 1
            ;;
        yum)
            set +e; yum check-update; local rc=$?; set -e
            [[ "$rc" -eq 0 || "$rc" -eq 100 ]] || return 1
            ;;
        pacman) pacman -Sy --noconfirm ;;
        zypper) zypper --non-interactive refresh ;;
    esac
}

upgrade_packages() {
    case "$PKG_MANAGER" in
        apt)
            dpkg_configure_all || true
            apt_get install -y -f </dev/null || true
            apt_get upgrade -y </dev/null
            dpkg_configure_all || true
            ;;
        dnf) dnf upgrade -y --best ;;
        yum) yum update -y ;;
        pacman) pacman -Syu --noconfirm ;;
        zypper) zypper --non-interactive update -y ;;
    esac
}

# Debian 发行版代号 → 下一版代号（官方升级路径）
debian_next_codename() {
    case "$1" in
        jessie) echo stretch ;;
        stretch) echo buster ;;
        buster) echo bullseye ;;
        bullseye) echo bookworm ;;
        bookworm) echo trixie ;;
        trixie) echo forky ;;
        *) echo "" ;;
    esac
}

# Debian 大版本升级：官方方式是替换源为下一版代号后 full-upgrade（do-release-upgrade 仅 Ubuntu 有）
dist_upgrade_debian() {
    local cur next bak
    cur=$(awk -F= '/^VERSION_CODENAME/{print $2}' /etc/os-release | tr -d '"')
    next=$(debian_next_codename "$cur")
    if [[ -z "$next" ]]; then
        log "${RED}无法确定 Debian ${cur} 的下一版本代号，跳过升级${NC}"
        return 1
    fi
    log "${GREEN}检测到当前 Debian ${cur}，目标版本：${next}${NC}"
    if command -v distro-info &>/dev/null; then
        local stable
        stable=$(distro-info --stable 2>/dev/null)
        if [[ -n "$stable" && "$stable" == "$cur" ]]; then
            log "${YELLOW}注意：${next} 尚未正式发布（当前稳定版仍为 ${stable}），升级属于 testing 版本，风险自负${NC}"
        fi
    else
        log "${YELLOW}注意：${next} 可能尚未正式发布，若软件源中不存在将自动回滚${NC}"
    fi

    bak="/etc/apt/sources.list.d.bak.up.$(date +%s)"
    mkdir -p "$bak"
    cp -r /etc/apt/sources.list.d/. "$bak/" 2>/dev/null || true
    cp /etc/apt/sources.list "$bak/sources.list" 2>/dev/null || true

    # 替换所有源中的当前代号（兼容 deb822 .sources 与旧式 sources.list）
    if [[ -f /etc/apt/sources.list ]]; then
        sed -i -E "s/\b${cur}\b/${next}/g" /etc/apt/sources.list
    fi
    sed -i -E "s/\b${cur}\b/${next}/g" /etc/apt/sources.list.d/*.sources 2>/dev/null || true

    log "${GREEN}已替换软件源 ${cur} → ${next}，开始更新并升级${NC}"
    if ! apt_get update; then
        log "${RED}软件源更新失败，回滚软件源配置${NC}"
        rm -rf /etc/apt/sources.list.d
        cp -r "$bak" /etc/apt/sources.list.d
        cp "$bak/sources.list" /etc/apt/sources.list 2>/dev/null || true
        return 1
    fi
    apt_get full-upgrade -y </dev/null
}

dist_upgrade() {
    case "$PKG_MANAGER" in
        apt)
            local os_id
            os_id=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
            if [[ "$os_id" == "ubuntu" ]] || command -v do-release-upgrade &>/dev/null; then
                apt_get install -y update-manager-core 2>/dev/null || true
                DEBIAN_FRONTEND=noninteractive \
                    do-release-upgrade -f DistUpgradeViewNonInteractive
            elif [[ "$os_id" == "debian" ]]; then
                dist_upgrade_debian
            else
                log "${YELLOW}apt 系发行版（${os_id:-未知}）不支持自动大版本升级，请手动处理${NC}"
            fi
            ;;
        dnf|yum)
            # 检测当前大版本
            local current_ver distro_hint=""
            current_ver=$(rpm -q --queryformat '%{VERSION}' alinux-release 2>/dev/null | cut -d. -f1)
            if [ -n "$current_ver" ]; then
                distro_hint="Alibaba Cloud Linux"
            else
                current_ver=$(rpm -q --queryformat '%{VERSION}' centos-release 2>/dev/null | cut -d. -f1)
                [ -n "$current_ver" ] && distro_hint="CentOS"
            fi
            [ -z "$current_ver" ] && current_ver=$(rpm -E "%{rhel}" 2>/dev/null | cut -d. -f1)
            [ -z "$current_ver" ] && current_ver=$(rpm -q --queryformat '%{VERSION}' redhat-release 2>/dev/null | cut -d. -f1)

            if [ -z "$current_ver" ] || ! [[ "$current_ver" =~ ^[0-9]+$ ]]; then
                log "${RED}无法检测当前系统大版本，跳过升级${NC}"
                return 1
            fi

            # Alibaba Cloud Linux 的 releasever 映射插件不支持自定义版本号
            if [[ "$distro_hint" == "Alibaba Cloud Linux" ]]; then
                log "${YELLOW}${distro_hint} ${current_ver} 不支持通过 --releasever 自动升级。${NC}"
                echo -e "\n${BLUE}可升级目标版本：${NC}"
                echo -e "  ${CYAN}1)${NC} alinux$((current_ver + 1)) 标准版"
                echo -e "  ${CYAN}2)${NC} alinux$((current_ver + 1)) Agentic 版"
                local edition_choice
                read -p "$(echo -e "${YELLOW}请选择要升级到的版本 (1/2): ${NC}")" -n 1 -r edition_choice || true
                echo
                local edition_suffix=""
                case "${edition_choice:-1}" in
                    2) edition_suffix="-agentic" ;;
                    *) edition_suffix="" ;;
                esac
                log "${GREEN}选择: alinux$((current_ver + 1))${edition_suffix:-标准版}${NC}"
                log "${YELLOW}开始替换仓库并升级，耗时较长，升级后需重启${NC}"
                # 备份原仓库
                cp -r /etc/yum.repos.d "/etc/yum.repos.d.bak.$(date +%s)" 2>/dev/null || true
                # 替换仓库 URL 中的版本号
                sed -i "s/alinux${current_ver}/alinux$((current_ver + 1))${edition_suffix}/g" /etc/yum.repos.d/*.repo 2>/dev/null || true
                # 安装新版本 release 包（优先本地镜像，失败后回退公网）
                local release_url="http://mirrors.aliyun.com/alinux/$((current_ver + 1))${edition_suffix}/os/x86_64/Packages/alinux-release-$((current_ver + 1))-1.al$((current_ver + 1)).noarch.rpm"
                "$PKG_MANAGER" install -y "$release_url" 2>/dev/null || {
                    log "${YELLOW}公网镜像不可用，尝试阿里云内网镜像${NC}"
                    release_url="http://mirrors.cloud.aliyuncs.com/alinux/$((current_ver + 1))${edition_suffix}/os/x86_64/Packages/alinux-release-$((current_ver + 1))-1.al$((current_ver + 1)).noarch.rpm"
                    "$PKG_MANAGER" install -y "$release_url" 2>/dev/null || true
                }
                "$PKG_MANAGER" clean all 2>/dev/null || true
                "$PKG_MANAGER" upgrade -y </dev/null || {
                    log "${RED}升级失败，请检查仓库配置或网络${NC}"
                    log "${YELLOW}备份位于: /etc/yum.repos.d.bak.*${NC}"
                    return 1
                }
                return 0
            fi

            local target_ver=$((current_ver + 1))
            log "${GREEN}检测到当前大版本: ${current_ver}（${distro_hint:-RHEL 系}），尝试升级至: ${target_ver}${NC}"
            log "${YELLOW}开始大版本升级（dnf --releasever=${target_ver}），耗时较长，升级后需重启${NC}"
            set +e
            "$PKG_MANAGER" upgrade --releasever="${target_ver}" -y </dev/null 2>&1 | \
                grep -v '^Traceback\|^  File\|^KeyError\|/usr/lib/python'
            local rc=${PIPESTATUS[0]}
            set -e
            # dnf --releasever 失败时给出引导
            if [ "$rc" -ne 0 ]; then
                log "${RED}大版本升级失败，常见原因：${NC}"
                log "${RED}  1. 目标版本仓库尚未发布或不可用${NC}"
                log "${RED}  2. 当前发行版不支持 --releasever 方式升级（如 Alibaba Cloud Linux）${NC}"
                log "${YELLOW}  请查阅官方文档手动升级，或更换发行版后重试${NC}"
                return 1
            fi
            ;;
        zypper) zypper --non-interactive dist-upgrade -y ;;
        *)
            log "${YELLOW}${PKG_MANAGER} 不支持自动大版本升级${NC}"
            ;;
    esac
}

clean_system() {
    case "$PKG_MANAGER" in
        apt)
            apt_get autoremove -y
            apt_get autoclean -y
            apt_get clean
            ;;
        dnf) dnf autoremove -y && dnf clean all ;;
        yum) yum autoremove -y && yum clean all ;;
        pacman)
            pacman -Sc --noconfirm
            local orphans
            orphans=$(pacman -Qtdq 2>/dev/null || true)
            [[ -n "$orphans" ]] && echo "$orphans" | xargs -r pacman -Rns --noconfirm || true
            ;;
        zypper)
            zypper --non-interactive clean --all
            local pkgs
            pkgs=$(zypper --non-interactive packages --unneeded 2>/dev/null | awk '/^i/ {print $3}' | tr '\n' ' ')
            [[ -n "$pkgs" ]] && zypper --non-interactive remove -y $pkgs || true
            ;;
    esac
    find /tmp /var/tmp -mindepth 1 -maxdepth 1 -type f -mtime +7 -delete 2>/dev/null || true
    find /tmp /var/tmp -mindepth 1 -maxdepth 1 -type d -empty -mtime +7 -delete 2>/dev/null || true
}

enable_auto_update() {
    case "$PKG_MANAGER" in
        apt)
            preseed_unattended_upgrades
            apt_get install -y unattended-upgrades </dev/null
            # 若包已装过仍触发 debconf，强制非交互重配置
            env DEBIAN_FRONTEND=noninteractive \
                dpkg-reconfigure -f noninteractive unattended-upgrades 2>/dev/null || true
            systemctl enable --now unattended-upgrades 2>/dev/null || true
            ;;
        dnf)
            dnf install -y dnf-automatic
            systemctl enable --now dnf-automatic.timer
            ;;
        yum)
            yum install -y yum-cron
            systemctl enable --now yum-cron
            ;;
        *)
            log "${YELLOW}当前系统未配置自动更新，已跳过${NC}"
            ;;
    esac
}

restart_proxy_services() {
    local svc restarted=0
    for svc in "${SERVICES_TO_RESTART[@]}"; do
        if systemctl list-unit-files "${svc}.service" &>/dev/null && systemctl is-enabled "${svc}" &>/dev/null; then
            if systemctl is-active --quiet "${svc}"; then
                systemctl restart "${svc}" && log "${GREEN}已重启服务：${svc}${NC}" && restarted=1
            fi
        fi
    done
    [[ "$restarted" -eq 0 ]] && log "${GREEN}无需重启代理服务${NC}"
}

needs_reboot() {
    [[ -f /var/run/reboot-required ]] && return 0
    if command -v needs-restarting &>/dev/null; then
        needs-restarting -r &>/dev/null
        # needs-restarting -r：退出码 1 = 需要重启，0 = 不需要
        [[ $? -eq 1 ]] && return 0
        return 1
    fi
    return 1
}

main() {
    require_root

    echo -e "\n${GREEN}===== Linux 系统升级+清理脚本（支持国内自研系统）=====${NC}"

    mkdir -p "$(dirname "$LOG_FILE")"
    touch "$LOG_FILE"

    detect_system
    detect_held_packages
    pro_ensure_attached
    check_disk_space
    ask_version_upgrade
    ask_holds

    run_step "更新软件源索引" update_index
    run_step "更新软件包（${PKG_MANAGER} upgrade）" upgrade_packages

    if [[ "$DO_DIST_UPGRADE" -eq 1 ]]; then
        log "${YELLOW}注意：版本升级耗时较长，部分系统升级后需手动重启${NC}"
        run_step "大版本升级" dist_upgrade
    else
        echo -e "\n${YELLOW}跳过版本升级，仅完成系统组件更新${NC}"
    fi

    ask_rehold

    if [[ "$DO_CLEAN" -eq 1 ]]; then
        run_step "清理无用依赖与过期临时文件" clean_system
    fi

    if [[ "$DO_AUTO_UPDATE" -eq 1 ]]; then
        run_step "配置自动安全更新" enable_auto_update
    else
        log "${GREEN}已跳过自动安全更新${NC}"
    fi

    restart_proxy_services

    echo -e "\n${GREEN}===== 升级+清理操作全部完成！${NC}"
    echo -e "${YELLOW}说明：${NC}"
    if [[ "$DO_DIST_UPGRADE" -eq 1 ]]; then
        echo -e "0. 已执行版本升级，必须重启系统：sudo reboot"
    elif needs_reboot; then
        echo -e "0. 检测到系统更新，建议重启：sudo reboot"
    fi
    echo -e "1. 自动安全更新说明："
    echo -e "   - Debian/Ubuntu/麒麟/统信：通过 unattended-upgrades 自动更新安全补丁"
    echo -e "   - RHEL/CentOS/欧拉/龙蜥：通过 yum-cron/dnf-automatic 每周自动更新"
    echo -e "   - Arch/openSUSE：通过系统定时器每周自动更新"
    echo -e "2. 国内用户若更新速度慢，可切换阿里云/华为云/清华源后重新运行"

    pro_auto_detach
}

main "$@"
