#!/bin/bash

# KernelSU Module Builder
# 构建和打包KernelSU模块的工具

set -euo pipefail

# 默认配置
BUILD_DIR="build"
DIST_DIR="dist"
CONFIG_FILE="build.conf"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 显示帮助信息
show_help() {
    cat << EOF
KernelSU Module Builder - 构建和打包KernelSU模块

用法: ksm-build [选项] [目标]

选项:
    -c, --config <file>     指定配置文件 (默认: build.conf)
    -o, --output <dir>      指定输出目录 (默认: dist)
    -b, --build-dir <dir>   指定构建目录 (默认: build)
    -v, --verbose           显示详细输出
    -h, --help              显示此帮助信息
    --clean                 清理构建文件
    --debug                 启用调试模式

目标:
    build      - 构建模块 (默认)
    package    - 打包模块
    install    - 安装到设备
    test       - 运行测试
    clean      - 清理构建文件
    all        - 执行完整构建流程

配置文件示例 (build.conf):
    MODULE_NAME=MyModule
    MODULE_VERSION=v1.0
    MODULE_AUTHOR=YourName
    ENABLE_WEBUI=true
    ENABLE_COMPRESSION=true
    EXCLUDE_PATTERNS="*.tmp,*.log,node_modules"

示例:
    ksm-build
    ksm-build package
    ksm-build --config custom.conf --verbose all
    ksm-build --clean

EOF
}

# 错误处理
error_exit() {
    echo -e "${RED}错误: $1${NC}" >&2
    exit 1
}

# 成功信息
success_msg() {
    echo -e "${GREEN}✓ $1${NC}"
}

# 警告信息
warning_msg() {
    echo -e "${YELLOW}⚠ $1${NC}"
}

# 信息输出
info_msg() {
    echo -e "${BLUE}ℹ $1${NC}"
}

# 详细输出
verbose_msg() {
    if [ "$VERBOSE" = "true" ]; then
        echo -e "${NC}  $1${NC}"
    fi
}

# 调试输出
debug_msg() {
    if [ "$DEBUG" = "true" ]; then
        echo -e "${YELLOW}[DEBUG] $1${NC}"
    fi
}

# 加载配置文件
load_config() {
    local config_file="$1"
    
    # 默认配置
    MODULE_NAME=""
    MODULE_VERSION="v1.0"
    MODULE_AUTHOR="Unknown"
    MODULE_DESCRIPTION=""
    ENABLE_WEBUI="false"
    ENABLE_COMPRESSION="true"
    EXCLUDE_PATTERNS="*.tmp,*.log,*.bak,node_modules,.git,.vscode"
    CUSTOM_SCRIPTS=""
    
    if [ -f "$config_file" ]; then
        debug_msg "加载配置文件: $config_file"
        source "$config_file"
        success_msg "配置文件已加载"
    else
        warning_msg "配置文件不存在: $config_file"
        
        # 尝试从module.prop获取信息
        if [ -f "module.prop" ]; then
            debug_msg "从module.prop获取模块信息"
            MODULE_NAME=$(grep "^id=" module.prop | cut -d'=' -f2)
            MODULE_VERSION=$(grep "^version=" module.prop | cut -d'=' -f2)
            MODULE_AUTHOR=$(grep "^author=" module.prop | cut -d'=' -f2)
            MODULE_DESCRIPTION=$(grep "^description=" module.prop | cut -d'=' -f2)
            
            if [ -n "$MODULE_NAME" ]; then
                success_msg "从module.prop获取模块信息: $MODULE_NAME"
            fi
        fi
    fi
    
    # 验证必需配置
    if [ -z "$MODULE_NAME" ]; then
        error_exit "未设置MODULE_NAME，请在配置文件中指定或确保module.prop文件存在"
    fi
}

# 创建构建目录
create_build_dirs() {
    debug_msg "创建构建目录"
    
    mkdir -p "$BUILD_DIR"
    mkdir -p "$DIST_DIR"
    
    success_msg "构建目录已创建: $BUILD_DIR, $DIST_DIR"
}

# 清理构建文件
clean_build() {
    info_msg "清理构建文件..."
    
    if [ -d "$BUILD_DIR" ]; then
        rm -rf "$BUILD_DIR"
        success_msg "已清理构建目录: $BUILD_DIR"
    fi
    
    if [ -d "$DIST_DIR" ]; then
        rm -rf "$DIST_DIR"
        success_msg "已清理输出目录: $DIST_DIR"
    fi
    
    # 清理临时文件
    find . -name "*.tmp" -delete 2>/dev/null || true
    find . -name "*.bak" -delete 2>/dev/null || true
    
    success_msg "构建文件清理完成"
}

# 复制源文件
copy_source_files() {
    info_msg "复制源文件到构建目录..."
    
    local build_path="$BUILD_DIR/$MODULE_NAME"
    mkdir -p "$build_path"
    
    # 创建排除列表
    local exclude_args=""
    IFS=',' read -ra EXCLUDE_ARRAY <<< "$EXCLUDE_PATTERNS"
    for pattern in "${EXCLUDE_ARRAY[@]}"; do
        exclude_args="$exclude_args --exclude=$pattern"
    done
    
    # 排除构建和输出目录
    exclude_args="$exclude_args --exclude=$BUILD_DIR --exclude=$DIST_DIR"
    
    verbose_msg "排除模式: $EXCLUDE_PATTERNS"
    
    # 复制文件
    rsync -av $exclude_args . "$build_path/" > /dev/null
    
    success_msg "源文件已复制到: $build_path"
}

# 处理WebUI文件
process_webui() {
    if [ "$ENABLE_WEBUI" = "true" ]; then
        local webui_path="$BUILD_DIR/$MODULE_NAME/webui"
        
        if [ -d "$webui_path" ]; then
            info_msg "处理WebUI文件..."
            
            # 压缩CSS和JS文件 (如果有相关工具)
            if command -v uglifyjs >/dev/null 2>&1; then
                find "$webui_path" -name "*.js" -exec uglifyjs {} -o {} \; 2>/dev/null || true
                verbose_msg "JavaScript文件已压缩"
            fi
            
            if command -v cleancss >/dev/null 2>&1; then
                find "$webui_path" -name "*.css" -exec cleancss -o {} {} \; 2>/dev/null || true
                verbose_msg "CSS文件已压缩"
            fi
            
            success_msg "WebUI文件处理完成"
        else
            warning_msg "WebUI目录不存在，跳过WebUI处理"
        fi
    fi
}

# 运行自定义脚本
run_custom_scripts() {
    if [ -n "$CUSTOM_SCRIPTS" ]; then
        info_msg "运行自定义构建脚本..."
        
        IFS=',' read -ra SCRIPT_ARRAY <<< "$CUSTOM_SCRIPTS"
        for script in "${SCRIPT_ARRAY[@]}"; do
            if [ -f "$script" ]; then
                verbose_msg "执行脚本: $script"
                bash "$script" "$BUILD_DIR/$MODULE_NAME"
                success_msg "脚本执行完成: $script"
            else
                warning_msg "脚本不存在: $script"
            fi
        done
    fi
}

# 验证模块文件
validate_module() {
    info_msg "验证模块文件..."
    
    local module_path="$BUILD_DIR/$MODULE_NAME"
    local errors=0
    
    # 检查必需文件
    local required_files=("module.prop" "META-INF/com/google/android/update-binary" "META-INF/com/google/android/updater-script")
    
    for file in "${required_files[@]}"; do
        if [ ! -f "$module_path/$file" ]; then
            echo -e "${RED}✗ 缺少必需文件: $file${NC}"
            ((errors++))
        else
            verbose_msg "✓ 文件存在: $file"
        fi
    done
    
    # 检查module.prop格式
    if [ -f "$module_path/module.prop" ]; then
        local required_props=("id" "name" "version" "versionCode" "author" "description")
        
        for prop in "${required_props[@]}"; do
            if ! grep -q "^$prop=" "$module_path/module.prop"; then
                echo -e "${RED}✗ module.prop缺少属性: $prop${NC}"
                ((errors++))
            else
                verbose_msg "✓ 属性存在: $prop"
            fi
        done
    fi
    
    # 检查脚本文件权限
    local script_files=("service.sh" "post-fs-data.sh" "uninstall.sh")
    
    for script in "${script_files[@]}"; do
        if [ -f "$module_path/$script" ]; then
            if [ ! -x "$module_path/$script" ]; then
                chmod +x "$module_path/$script"
                verbose_msg "✓ 设置执行权限: $script"
            fi
        fi
    done
    
    if [ $errors -eq 0 ]; then
        success_msg "模块验证通过"
        return 0
    else
        error_exit "模块验证失败，发现 $errors 个错误"
    fi
}

# 打包模块
package_module() {
    info_msg "打包模块..."
    
    local module_path="$BUILD_DIR/$MODULE_NAME"
    local package_name="${MODULE_NAME}_${MODULE_VERSION}.zip"
    local package_path="$DIST_DIR/$package_name"
    
    # 确保输出目录存在
    mkdir -p "$DIST_DIR"
    
    # 创建ZIP包
    cd "$module_path"
    
    if [ "$ENABLE_COMPRESSION" = "true" ]; then
        zip -r "$package_path" . -x "*.tmp" "*.log" > /dev/null
    else
        zip -r -0 "$package_path" . -x "*.tmp" "*.log" > /dev/null
    fi
    
    cd - > /dev/null
    
    # 计算文件大小
    local size=$(stat -f%z "$package_path" 2>/dev/null || stat -c%s "$package_path" 2>/dev/null || echo "unknown")
    local size_mb=$(echo "scale=2; $size / 1024 / 1024" | bc 2>/dev/null || echo "unknown")
    
    success_msg "模块打包完成: $package_name"
    info_msg "包大小: ${size_mb}MB"
    info_msg "包路径: $package_path"
}

# 安装模块到设备
install_module() {
    info_msg "安装模块到设备..."
    
    local package_name="${MODULE_NAME}_${MODULE_VERSION}.zip"
    local package_path="$DIST_DIR/$package_name"
    
    if [ ! -f "$package_path" ]; then
        error_exit "模块包不存在: $package_path，请先运行构建和打包"
    fi
    
    # 检查ADB连接
    if ! command -v adb >/dev/null 2>&1; then
        error_exit "未找到ADB工具，请安装Android SDK"
    fi
    
    if ! adb devices | grep -q "device$"; then
        error_exit "未检测到ADB设备连接"
    fi
    
    # 推送模块到设备
    adb push "$package_path" "/data/local/tmp/" || error_exit "无法推送模块到设备"
    
    # 使用KernelSU安装模块 (需要root权限)
    adb shell "su -c 'mkdir -p /data/adb/modules_update'" || warning_msg "无法创建模块更新目录"
    adb shell "su -c 'cd /data/local/tmp && unzip -o $package_name -d /data/adb/modules_update/'" || error_exit "无法解压模块"
    
    success_msg "模块已安装到设备，请重启以生效"
}

# 运行测试
run_tests() {
    info_msg "运行模块测试..."
    
    local module_path="$BUILD_DIR/$MODULE_NAME"
    local test_passed=0
    local test_failed=0
    
    # 基本文件结构测试
    verbose_msg "测试1: 检查文件结构"
    if validate_module 2>/dev/null; then
        echo -e "${GREEN}✓ 文件结构测试通过${NC}"
        ((test_passed++))
    else
        echo -e "${RED}✗ 文件结构测试失败${NC}"
        ((test_failed++))
    fi
    
    # 脚本语法测试
    verbose_msg "测试2: 检查脚本语法"
    local script_errors=0
    
    find "$module_path" -name "*.sh" -type f | while read -r script; do
        if ! bash -n "$script" 2>/dev/null; then
            echo -e "${RED}✗ 脚本语法错误: $script${NC}"
            ((script_errors++))
        fi
    done
    
    if [ $script_errors -eq 0 ]; then
        echo -e "${GREEN}✓ 脚本语法测试通过${NC}"
        ((test_passed++))
    else
        echo -e "${RED}✗ 脚本语法测试失败${NC}"
        ((test_failed++))
    fi
    
    # WebUI文件测试
    if [ "$ENABLE_WEBUI" = "true" ] && [ -d "$module_path/webui" ]; then
        verbose_msg "测试3: 检查WebUI文件"
        
        local webui_errors=0
        
        # 检查HTML文件
        if [ -f "$module_path/webui/index.html" ]; then
            if command -v tidy >/dev/null 2>&1; then
                if ! tidy -q -e "$module_path/webui/index.html" 2>/dev/null; then
                    ((webui_errors++))
                fi
            fi
        else
            ((webui_errors++))
        fi
        
        if [ $webui_errors -eq 0 ]; then
            echo -e "${GREEN}✓ WebUI文件测试通过${NC}"
            ((test_passed++))
        else
            echo -e "${RED}✗ WebUI文件测试失败${NC}"
            ((test_failed++))
        fi
    fi
    
    # 显示测试结果
    echo ""
    info_msg "测试结果: $test_passed 个通过, $test_failed 个失败"
    
    if [ $test_failed -eq 0 ]; then
        success_msg "所有测试通过!"
        return 0
    else
        error_exit "测试失败，请检查并修复问题"
    fi
}

# 主函数
main() {
    local config_file="$CONFIG_FILE"
    local target="build"
    local clean_only="false"
    
    # 全局变量
    VERBOSE="false"
    DEBUG="false"
    
    # 解析命令行参数
    while [[ $# -gt 0 ]]; do
        case $1 in
            -c|--config)
                config_file="$2"
                shift 2
                ;;
            -o|--output)
                DIST_DIR="$2"
                shift 2
                ;;
            -b|--build-dir)
                BUILD_DIR="$2"
                shift 2
                ;;
            -v|--verbose)
                VERBOSE="true"
                shift
                ;;
            --debug)
                DEBUG="true"
                shift
                ;;
            --clean)
                clean_only="true"
                shift
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            -*)
                error_exit "未知选项: $1"
                ;;
            *)
                target="$1"
                shift
                ;;
        esac
    done
    
    # 如果只是清理，执行清理后退出
    if [ "$clean_only" = "true" ]; then
        clean_build
        exit 0
    fi
    
    info_msg "KernelSU模块构建器"
    info_msg "目标: $target"
    
    # 加载配置
    load_config "$config_file"
    
    # 根据目标执行相应操作
    case "$target" in
        "clean")
            clean_build
            ;;
        "build")
            create_build_dirs
            copy_source_files
            process_webui
            run_custom_scripts
            validate_module
            success_msg "模块构建完成!"
            ;;
        "package")
            if [ ! -d "$BUILD_DIR/$MODULE_NAME" ]; then
                info_msg "构建目录不存在，开始构建..."
                create_build_dirs
                copy_source_files
                process_webui
                run_custom_scripts
                validate_module
            fi
            package_module
            ;;
        "install")
            if [ ! -f "$DIST_DIR/${MODULE_NAME}_${MODULE_VERSION}.zip" ]; then
                info_msg "模块包不存在，开始完整构建流程..."
                create_build_dirs
                copy_source_files
                process_webui
                run_custom_scripts
                validate_module
                package_module
            fi
            install_module
            ;;
        "test")
            if [ ! -d "$BUILD_DIR/$MODULE_NAME" ]; then
                info_msg "构建目录不存在，开始构建..."
                create_build_dirs
                copy_source_files
                process_webui
                run_custom_scripts
            fi
            run_tests
            ;;
        "all")
            create_build_dirs
            copy_source_files
            process_webui
            run_custom_scripts
            validate_module
            run_tests
            package_module
            success_msg "完整构建流程完成!"
            ;;
        *)
            error_exit "未知目标: $target"
            ;;
    esac
}

# 执行主函数
main "$@"
