#!/bin/bash

# 设置脚本名称和颜色代码
SCRIPT_NAME="Kernel Cleanup Script"
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color

# 要保留的内核版本前缀
KEEP_VERSION="6.2.0"
# 用于匹配内核镜像和头文件的通用模式
KERNEL_PATTERN="linux-(image|headers|modules|module)"

# 是否自动删除所有旧内核（包括 generic 元包）且无需确认：yes/no
AUTO_PURGE_ALL="${AUTO_PURGE_ALL:-yes}"

echo -e "${YELLOW}--- ${SCRIPT_NAME} ---${NC}"

# 1. 检查是否以 root 权限运行
if [[ $EUID -ne 0 ]]; then
   echo -e "${RED}错误：请使用 sudo 或 root 权限运行此脚本。${NC}"
   exit 1
fi

# 2. 获取当前正在运行的内核版本
CURRENT_KERNEL=$(uname -r)
echo -e "${GREEN}当前正在运行的内核：${CURRENT_KERNEL}${NC}"

# 3. 先解除非 KEEP_VERSION 的 linux-* 包的 hold，以便可以被清理
echo "--- 解除非 $KEEP_VERSION 相关内核包的 hold 状态（如果存在） ---"
HELD_PKGS=$(apt-mark showhold 2>/dev/null | grep '^linux-' || true)
if [[ -n "$HELD_PKGS" ]]; then
    while IFS= read -r PKG; do
        if [[ -z "$PKG" ]]; then
            continue
        fi
        if [[ "$PKG" == *"$KEEP_VERSION"* ]]; then
            echo "  保留 hold: $PKG (匹配保留版本: $KEEP_VERSION)"
        else
            echo "  解除 hold: $PKG"
            sudo apt-mark unhold "$PKG" || true
        fi
    done <<< "$HELD_PKGS"
else
    echo "  没有发现已 hold 的 linux-* 包。"
fi

# 4. 循环搜索并删除所有非 KEEP_VERSION 的内核相关软件包
ROUND=1
while :; do
    echo "--- 第 $ROUND 轮：扫描需要删除的旧内核包 ---"

    # 匹配所有包含 'linux-' 并且是 'image' 或 'headers' 或 'modules' 的包
    INSTALLED_PACKAGES=$(dpkg --list 2>/dev/null | awk '/^ii/ {print $2}' | grep -E "$KERNEL_PATTERN" || true)

    PACKAGES_TO_REMOVE=""

    while IFS= read -r PACKAGE; do
        [[ -z "$PACKAGE" ]] && continue

        # 检查包名是否包含要保留的版本
        if [[ "$PACKAGE" == *"$KEEP_VERSION"* ]]; then
            echo -e "  [${GREEN}保留${NC}] $PACKAGE (匹配保留版本: $KEEP_VERSION)"

        # 检查包名是否是当前正在运行的内核
        elif [[ "$PACKAGE" == *"$CURRENT_KERNEL"* ]]; then
            echo -e "  [${RED}注意${NC}] $PACKAGE (是正在运行的内核：必须保留)"

        # 检查是否是通用的元包 (如 linux-image-generic)
        elif [[ "$PACKAGE" == *"linux-image-generic"* ]] || [[ "$PACKAGE" == *"linux-headers-generic"* ]]; then
            echo -e "  [${RED}删除${NC}] $PACKAGE (不再保留通用元包)"
            PACKAGES_TO_REMOVE="$PACKAGES_TO_REMOVE $PACKAGE"

        # 否则，标记为删除
        else
            echo -e "  [${RED}删除${NC}] $PACKAGE"
            PACKAGES_TO_REMOVE="$PACKAGES_TO_REMOVE $PACKAGE"
        fi
    done <<< "$INSTALLED_PACKAGES"

    if [[ -z "$PACKAGES_TO_REMOVE" ]]; then
        echo -e "${GREEN}--- 没有找到需要删除的旧内核包。---${NC}"
        break
    fi

    echo -e "${YELLOW}--- 本轮将删除以下软件包: ---${NC}"
    echo "$PACKAGES_TO_REMOVE" | xargs -n 1

    if [[ "$AUTO_PURGE_ALL" == "yes" ]]; then
        echo -e "${YELLOW}AUTO_PURGE_ALL=yes，跳过确认，直接执行删除。${NC}"
        CONFIRMATION="yes"
    else
        # 用户确认环节
        read -r -p "输入 'yes' 继续删除操作，否则退出: " CONFIRMATION
    fi

    if [[ "$CONFIRMATION" == "yes" ]]; then
        echo -e "${YELLOW}--- 正在执行删除和清理操作（第 $ROUND 轮）... ---${NC}"

        # 使用 apt purge 彻底删除标记的包
        # shellcheck disable=SC2086 # 需要保留空格作为包的分隔符
        sudo apt purge -y $PACKAGES_TO_REMOVE || true
    else
        echo -e "${RED}操作已取消。${NC}"
        break
    fi

    ROUND=$((ROUND + 1))
done

echo -e "${YELLOW}--- 执行自动清理不再需要的依赖 ---${NC}"
sudo apt autoremove -y || true

echo -e "${YELLOW}--- 更新 GRUB 引导配置 ---${NC}"
sudo update-grub || true

echo -e "${GREEN}--- 内核清理完成！---${NC}"
echo -e "请运行 'dpkg --list | grep linux-image' 确认剩余内核。"

echo -e "${YELLOW}--- ${SCRIPT_NAME} 结束 ---${NC}"