#!/sbin/sh

####################################################
#
# Magisk/KernelSU/APatch 通用模块安装脚本
# 原始模板 by topjohnwu
# 汉化适配: l奋斗的小青年
# 多ROOT兼容: v250403
#
#####################################################

umask 022

# 全局变量
TMPDIR=/dev/tmp
PERSISTDIR=/sbin/.magisk/mirror/persist

rm -rf $TMPDIR 2>/dev/null
mkdir -p $TMPDIR

# 在加载 util_functions 前 echo
ui_print() { echo "$1"; }

# ==================== 环境检测 ====================
detect_root_solution() {
    ROOT_SOLUTION="unknown"
    
    # 检测 KernelSU
    if [ -d "/data/adb/ksu" ] || [ -f "/data/adb/ksud" ] || [ "$(getprop ro.kernel.ksu)" = "true" ]; then
        ROOT_SOLUTION="kernelsu"
        KSU=true
        ui_print "- 检测到 KernelSU 环境"
        return
    fi
    
    # 检测 APatch
    if [ -d "/data/adb/ap" ] || [ -f "/data/adb/apd" ] || [ "$(getprop ro.kernel.apatch)" = "true" ]; then
        ROOT_SOLUTION="apatch"
        APATCH=true
        ui_print "- 检测到 APatch 环境"
        return
    fi
    
    # 检测 Magisk
    if [ -d "/data/adb/magisk" ] || [ -f "/data/adb/magisk/util_functions.sh" ]; then
        ROOT_SOLUTION="magisk"
        MAGISK=true
        ui_print "- 检测到 Magisk 环境"
        return
    fi
    
    # 尝试通过 mount 检测
    if mount | grep -q "magisk"; then
        ROOT_SOLUTION="magisk"
        MAGISK=true
        ui_print "- 检测到 Magisk 环境"
    fi
}

# ==================== 加载工具函数 ====================
load_util_functions() {
    # Magisk 环境
    if [ -f "/data/adb/magisk/util_functions.sh" ]; then
        . /data/adb/magisk/util_functions.sh
        return 0
    fi
    
    # KernelSU 环境 - 使用内置函数
    if [ "$ROOT_SOLUTION" = "kernelsu" ]; then
        # KernelSU 兼容 Magisk 模块格式，定义必要函数
        grep_prop() {
            local REGEX="s/^$1=//p"
            shift
            local FILES="$@"
            [ -z "$FILES" ] && FILES='/system/build.prop /vendor/build.prop /product/build.prop /odm/build.prop /system_ext/build.prop'
            sed -n "$REGEX" $FILES 2>/dev/null | head -n 1
        }
        
        setup_flashable() {
            # KernelSU 不需要额外设置
            true
        }
        
        mount_partitions() {
            mount /data 2>/dev/null
        }
        
        api_level_arch_detect() {
            API=$(grep_prop ro.build.version.sdk)
            ABI=$(grep_prop ro.product.cpu.abi)
            if [ "$ABI" = "x86" ]; then
                ARCH=x86
                ABI32=x86
                IS64BIT=false
            elif [ "$ABI" = "arm64-v8a" ]; then
                ARCH=arm64
                ABI32=armeabi-v7a
                IS64BIT=true
            elif [ "$ABI" = "x86_64" ]; then
                ARCH=x64
                ABI32=x86
                IS64BIT=true
            else
                ARCH=arm
                ABI=armeabi
                ABI32=armeabi
                IS64BIT=false
            fi
        }
        
        boot_actions() { true; }
        recovery_actions() { true; }
        recovery_cleanup() { true; }
        
        return 0
    fi
    
    # APatch 环境 - 类似 KernelSU
    if [ "$ROOT_SOLUTION" = "apatch" ]; then
        grep_prop() {
            local REGEX="s/^$1=//p"
            shift
            local FILES="$@"
            [ -z "$FILES" ] && FILES='/system/build.prop /vendor/build.prop /product/build.prop /odm/build.prop /system_ext/build.prop'
            sed -n "$REGEX" $FILES 2>/dev/null | head -n 1
        }
        
        setup_flashable() { true; }
        mount_partitions() { mount /data 2>/dev/null; }
        api_level_arch_detect() {
            API=$(grep_prop ro.build.version.sdk)
            ABI=$(grep_prop ro.product.cpu.abi)
        }
        boot_actions() { true; }
        recovery_actions() { true; }
        recovery_cleanup() { true; }
        
        return 0
    fi
    
    # 未检测到支持的 ROOT 方案
    return 1
}

require_new_root() {
    ui_print "*******************************"
    ui_print " 请安装 Magisk / KernelSU / APatch ! "
    ui_print "*******************************"
    exit 1
}

is_legacy_script() {
    unzip -l "$ZIPFILE" install.sh 2>/dev/null | grep -q install.sh
    return $?
}

set_perm() {
    chown $2:$3 $1 || return 1
    chmod $4 $1 || return 1
    [ -z $5 ] && return 0
    selinuxcontext=$5
    [ $5 = "u:object_r:system_file:s0" ] || chcon $5 $1 2>/dev/null || true
}

set_perm_recursive() {
    find $1 -type d 2>/dev/null | while read dir; do
        set_perm $dir $2 $3 $4 $6
    done
    find $1 -type f 2>/dev/null | while read file; do
        set_perm $file $2 $3 $5 $6
    done
}

mktouch() {
    mkdir -p ${1%/*} 2>/dev/null
    [ -z $2 ] && touch $1 || echo $2 > $1
    chmod 644 $1
}

request_size_check() {
    reqSizeM=`du -ms $1 | cut -f1`
}

request_zip_size_check() {
    reqSizeM=`unzip -l "$1" | tail -n 1 | awk '{ print int(($1 - 1) / 1048576 + 1) }'`
}

####################################################
# 环境设置
####################################################

OUTFD=$2
ZIPFILE=$3

# 检测 ROOT 方案
detect_root_solution

# 加载工具函数
if ! load_util_functions; then
    require_new_root
fi

# 挂载分区
mount_partitions

# 检测版本和架构
api_level_arch_detect

# 安装 busybox 和二进制文件
if [ "$ROOT_SOLUTION" = "magisk" ]; then
    $BOOTMODE && boot_actions || recovery_actions
fi

####################################################
# 准备
####################################################

# 提取公共文件
unzip -o "$ZIPFILE" module.prop -d $TMPDIR >&2
[ ! -f $TMPDIR/module.prop ] && { ui_print "! 从 zip 中提取文件失败!"; exit 1; }

# 设置模块目录
if [ "$ROOT_SOLUTION" = "magisk" ]; then
    $BOOTMODE && MODDIRNAME=modules_update || MODDIRNAME=modules
else
    # KernelSU/APatch 直接使用 modules 目录
    MODDIRNAME=modules
fi

MODULEROOT=/data/adb/$MODDIRNAME
MODID=$(grep_prop id $TMPDIR/module.prop)
MODPATH=$MODULEROOT/$MODID
MODNAME=$(grep_prop name $TMPDIR/module.prop)

# 创建模块路径
rm -rf $MODPATH 2>/dev/null
mkdir -p $MODPATH

####################################################
# 安装
####################################################

if is_legacy_script; then
    unzip -oj "$ZIPFILE" module.prop install.sh uninstall.sh 'common/*' -d $TMPDIR >&2

    # 加载安装脚本
    . $TMPDIR/install.sh

    # 打印模块名称
    print_modname
    on_install

    # 加载自定义卸载脚本
    [ -f $TMPDIR/uninstall.sh ] && cp -af $TMPDIR/uninstall.sh $MODPATH/uninstall.sh

    # 取消挂载
    $SKIPMOUNT && touch $MODPATH/skip_mount

    # prop 文件
    $PROPFILE && cp -af $TMPDIR/system.prop $MODPATH/system.prop 2>/dev/null

    # 模块信息
    cp -af $TMPDIR/module.prop $MODPATH/module.prop

    # post-fs-data 模式脚本
    $POSTFSDATA && cp -af $TMPDIR/post-fs-data.sh $MODPATH/post-fs-data.sh

    # service 模式脚本
    $LATESTARTSERVICE && cp -af $TMPDIR/service.sh $MODPATH/service.sh

    ui_print "- 正在设置权限"
    set_permissions
else
    print_modname
    
    unzip -o "$ZIPFILE" customize.sh -d $MODPATH >&2

    if ! grep -q '^SKIPUNZIP=1$' $MODPATH/customize.sh 2>/dev/null; then
        ui_print "- 正在安装模块文件"
        unzip -o "$ZIPFILE" -x 'META-INF/*' -d $MODPATH >&2

        # 默认权限
        set_perm_recursive $MODPATH 0 0 0755 0644
    fi

    # 加载 customization 脚本
    [ -f $MODPATH/customize.sh ] && . $MODPATH/customize.sh
    
    # service 模式脚本
    $LATESTARTSERVICE && cp -af $TMPDIR/service.sh $MODPATH/service.sh 2>/dev/null
fi

# 处理 replace 文件夹
for TARGET in $REPLACE; do
    ui_print "- 正在删除目标文件: $TARGET"
    mktouch $MODPATH$TARGET/.replace
done

# Magisk 模式下更新信息
if [ "$ROOT_SOLUTION" = "magisk" ] && $BOOTMODE; then
    mktouch /data/adb/modules/$MODID/update
    cp -af $MODPATH/module.prop /data/adb/modules/$MODID/module.prop
fi

# 安装自定义 sepolicy 补丁
if [ -f $MODPATH/sepolicy.rule ] && [ -e $PERSISTDIR ]; then
    ui_print "- 安装自定义 sepolicy 补丁"
    PERSISTMOD=$PERSISTDIR/magisk/$MODID
    mkdir -p $PERSISTMOD
    cp -af $MODPATH/sepolicy.rule $PERSISTMOD/sepolicy.rule
fi

# 删除 placeholder 文件
rm -rf \
$MODPATH/system/placeholder $MODPATH/customize.sh \
$MODPATH/README.md $MODPATH/.git* 2>/dev/null

####################################################
# 结束
####################################################

cd /
[ "$ROOT_SOLUTION" = "magisk" ] && ! $BOOTMODE && recovery_cleanup
rm -rf $TMPDIR

ui_print "- 安装完成"
ui_print "- 重启后生效"

exit 0
