#!/bin/bash

# set -x
# set -e

hostname=$(hostname)
log() {
    timestamp=$(date -Iseconds)
    logger -t "dpkg_wrapper" "${timestamp} ${hostname} dpkg_wrapper: $1"
}

# 判断是否在 Live Build 环境的函数 (POSIX 兼容)
is_live_build() {
    if [ -d "/lib/live" ] || [ -d "/usr/lib/live" ]; then
        log "检测到Live Build环境: 存在/lib/live或/usr/lib/live"
        return 0
    fi
    
    if grep -q "boot=live" /proc/cmdline 2>/dev/null; then
        log "检测到Live Build环境: 内核参数包含boot=live"
        return 0
    fi
    
    if [ -e "/etc/live" ] || [ -e "/lib/live/mount/medium" ] || [ -e "/var/lib/live" ]; then
        log "检测到Live Build环境: 存在Live标志文件"
        return 0
    fi
    
    if [ -n "$LIVE_BUILD" ] || [ -n "$LB_BUILD_IMAGE" ]; then
        log "检测到Live Build环境: 存在Live环境变量"
        return 0
    fi
    
    return 1
}


# 判断是否为 Live CD 环境的函数（POSIX 兼容）
is_live_cd() {
    # 检查内核参数中是否包含 boot=casper
    if grep -q "boot=casper" /proc/cmdline 2>/dev/null; then
        log "检测到Live CD环境: 内核参数包含boot=casper"
        return 0
    fi

    return 1
}

is_normal_mode() {
    boot_mode=$(gdbus call --system \
        -d com.kylin.MaintainMode \
        -o /com/kylin/MaintainMode/Object \
        -m com.kylin.MaintainMode.interface.GetBootMode 2>/dev/null | awk -F\' '{print $2}' 2>/dev/null)

    if [ "$boot_mode" = "normal" ]; then
        log "检测到normal模式"
        return 0  # 是normal模式返回0
    fi
    
    log "当前不是normal模式: $boot_mode"
    return 1  # 不是normal模式返回1
}

# 判断是否在 unshare -m 创建的挂载命名空间中（POSIX 兼容）
is_unshare_mount_ns() {
    if [ ! -e "/proc/self/ns/mnt" ] || [ ! -e "/proc/1/ns/mnt" ]; then
        return 1
    fi
    
    current_mnt_ns=$(readlink /proc/self/ns/mnt 2>/dev/null)
    init_mnt_ns=$(readlink /proc/1/ns/mnt 2>/dev/null)
    
    if [ -z "$current_mnt_ns" ] || [ -z "$init_mnt_ns" ]; then
        return 1
    fi
    
    if [ "$current_mnt_ns" != "$init_mnt_ns" ]; then
        log "检测到unshare -m挂载命名空间: 当前命名空间($current_mnt_ns) != init命名空间($init_mnt_ns)"
        return 0
    fi
    
    return 1
}


# 检查是否应该执行操作
should_execute_operation() {
    # 如果在unshare空间，执行原生命令
    if is_unshare_mount_ns; then
        log "检测到unshare -m命名空间，执行原生命令"
        return 1
    fi

    # 如果不是Live Build环境 且 不是chroot环境 且 不是Live CD环境 且 是normal模式
    if ! is_live_build && ! $(ischroot) && ! is_live_cd && is_normal_mode; then
        log "满足所有条件: 非Live Build、非chroot、非Live CD、normal模式"
        return 0  # 应该执行操作
    fi
    

    
    # 记录不满足的具体条件
    if is_live_build; then
        log "不满足条件: 当前是Live Build环境"
    fi
    
    if $(ischroot); then
        log "不满足条件: 当前是chroot环境"
    fi
    
    if is_live_cd; then
        log "不满足条件: 当前是Live CD环境"
    fi
    
    if ! is_normal_mode; then
        log "不满足条件: 当前不是normal模式"
    fi
    
    return 1  # 不应该执行操作
}

# 处理多个包名操作
handle_multiple_packages() {
    local operation=$1  # 要执行的操作(install/remove)
    local exit_code=0
    log "operation:$operation"	    
    # 遍历所有参数
    shift   # 移除操作参数
    local options=()
    local packages=()
    
    local processing_options=true
    for arg in "$@"; do
        if [ "$processing_options" = true ] && [[ "$arg" == -* ]]; then
            options+=("$arg")
        elif [ "$processing_options" = true ] && [[ "$arg" == "--" ]]; then
            processing_options=false
        else
            processing_options=false
            packages+=("$arg")
        fi
    done
    log "处理带选项的安装: options=[${options[*]}], packages=[${packages[*]}]"

    
    for arg in "${packages[*]}"; do
        log "进入循环，处理参数: $arg"
        # 直接处理文件参数，转换为绝对路径
        absolute_path=$(realpath "$arg" 2>/dev/null || readlink -f "$arg" 2>/dev/null || echo "$arg")
        if [ "$operation" = "install" ]; then
            log "安装deb包: $absolute_path"
            result=$(/usr/bin/kypackage_check $absolute_path)
            if [[ "$result" =~ "将要安装的环境为kare" ]]; then
                log "通过kare安装软件包:${absolute_path}"
                /usr/bin/kypackage_inst "${absolute_path}"
            else
                log "通过kypackage_general安装软件包:${absolute_path}"
                /usr/bin/kypackage_general  dpkg.orig   ${options[*]} ${absolute_path}
                /usr/bin/kypackage_desktop  "--create" $absolute_path
            fi
        elif [ "$operation" = "unpack" ]; then
            log "解压deb包: $absolute_path"
            /usr/bin/kypackage_unpack "$absolute_path"
        fi
        current_exit_code=$?
        if [ $current_exit_code -ne 0 ]; then
            exit_code=$current_exit_code
        fi
    done
    
    return $exit_code
}

# 解析命令行参数
parse_arguments() {

    # 检查无效的参数组合
    local list_opt=0
    local pkg_opt=0
    local unknown_opt=0
    local configure_opt=0
    local unpack_opt=0
    
    for arg in "$@"; do
        case "$arg" in
            --unpack)
                unpack_opt=1
                ;;
            -l|--list)
                list_opt=$((list_opt + 1))
                ;;
            -i|--install|-P|--purge|-r|--remove|--unpack)
                pkg_opt=$((pkg_opt + 1))
                ;;
            --configure|-a|--pendinig)
                configure_opt=$((configure_opt + 1))
                ;;
            --*|-*)
                unknown_opt=$((unknown_opt + 1))
                ;;
        esac
    done

    # 有未知的参数且没有安装、卸载相关操作，直接转交dpkg
    if [ $unknown_opt -gt 0 ] && [ $pkg_opt -ne 1 ]; then
        log "存在未知的操作选项: $@ 执行原生dpkg"
        exec /usr/bin/dpkg.orig "$@"
        exit 1
    fi
    
    # 检验包列表和安装/卸载/解压冲突
    local pkg_or_list_opts=$((list_opt + pkg_opt + unpack_opt))
    if [ $pkg_or_list_opts -gt 1 ]; then
        log "错误: 操作符冲突 $@"
        exec /usr/bin/dpkg.orig "$@"
        exit 1
    fi

    # 检验configure参数完整性
    if [ $configure_opt -ne 0 ] && [ $configure_opt -ne 2 ]; then
        log "错误: configure操作异常 $@"
        exec /usr/bin/dpkg.orig "$@"
        exit 1
    fi
    
    # 检验configure
    local total_opts=$((list_opt + pkg_opt + configure_opt + unpack_opt))
    
    if [ $total_opts -gt 2 ]; then
        log "错误: configure操作与其他操作冲突 $@"
        exec /usr/bin/dpkg.orig "$@"
        exit 1
    fi
}

# 判断是否为通配符模式（包含 * 或 ?）
is_wildcard_pattern() {
    local pattern="$1"
    [[ "$pattern" == *"*"* ]] || [[ "$pattern" == *"?"* ]]
}

# 只有在非live-build且非chroot且是normal模式时才执行操作拦截
if  should_execute_operation; then
    parse_arguments "$@"
    
    # 需要阻止的操作类型
    case "$1" in
        --configure)
            log "通过wrapper执行操作操作: $1"
            exec /usr/bin/kypackage_configure
            exit $?
            ;;
        -i|--install)
            log "通过wrapper执行操作: $1"
            handle_multiple_packages install "$@"
            exit $?
            ;;

        -P|--purge|-r|--remove)
            log "通过wrapper执行操作: $1"
            shift #挪走操作符号
            for arg in "$@"; do
                if [[ "$arg" == -* ]]; then
                    continue
                fi
                log "尝试删除deb包: $arg"
                /usr/bin/kypackage_remove "$arg"
            done
            exit $?
            ;;

        --unpack)
            log "通过wrapper执行操作: $1"
            shift #挪走操作符号
            handle_multiple_packages unpack "$@"
            exit $?
            ;;
        
        -l|--list)
            log "通过wrapper执行操作: $1"
            shift
            
            full_list=$(/usr/bin/kypackage_list)
            
            if [ $# -gt 0 ]; then
                awk_patterns=""
                for pattern in "$@"; do
                    if is_wildcard_pattern "$pattern"; then
                        regex_pattern=$(echo "$pattern" | sed 's/\*/.*/g' | sed 's/?/./g' | sed 's/[][^$.+(){}|]/\\&/g')
                    else
                        regex_pattern="^$pattern$"
                    fi
                    
                    if [ -z "$awk_patterns" ]; then
                        awk_patterns="$regex_pattern"
                    else
                        awk_patterns="$awk_patterns|$regex_pattern"
                    fi
                done
                
                echo "$full_list" | awk -v patterns="$awk_patterns" '
                BEGIN {
                    split(patterns, pattern_array, "|")
                }
                /^ii|^hi/ {
                    pkg_name = $2
                    for (i in pattern_array) {
                        if (pkg_name ~ pattern_array[i]) {
                            print $0
                            break
                        }
                    }
                }'
            else
                # 如果没有额外参数，则显示所有包
                if [ -n "$full_list" ]; then
                    printf '%s\n' "$full_list" 2>/dev/null || true
                fi
            fi
            exit 0
            ;;
        *)
            log "通过原生dpkg执行操作: $1"
            exec /usr/bin/dpkg.orig "$@" 2>&1
            ;;
    esac
else
    log "不满足拦截条件，通过原生dpkg执行操作: $1"
    exec /usr/bin/dpkg.orig "$@" 2>&1
fi