#!/bin/sh

RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
PURPLE='\033[1;35m'
NC='\033[0m'
BS="\033[1;37m"

bb="2.5"
lj="https://opop.qhylri.fun//word/obtain.php?user=188166&id=1"

check_commands() {
    for cmd in curl sed base64 xxd gzip; do
        if ! command -v "$cmd" >/dev/null 2>&1; then
            echo -e "${RED}错误: 缺少必要命令 $cmd${NC}"
            exit 1
        fi
    done
}

get_cloud_data() {
    cloud_data=$(curl -s --connect-timeout 10 "$lj") || {
        echo -e "${YELLOW}警告: 无法获取云端数据，使用本地版本${NC}"
        return 1
    }
    
    mz=$(echo "$cloud_data" | sed -n 's/.*名字【\([^】]*\)】.*/\1/p')
    gg=$(echo "$cloud_data" | sed -n 's/.*公告【\([^】]*\)】.*/\1/p')
    gxlj=$(echo "$cloud_data" | sed -n 's/.*更新链接【\([^】]*\)】.*/\1/p')
    bbs=$(echo "$cloud_data" | sed -n 's/.*版本【\([^】]*\)】.*/\1/p')
    
    [ -z "$bbs" ] && bbs="$bb"
}

show_header() {
    echo -e "${YELLOW}================================================"
    echo -e "${GREEN}                 shell脚本加密工具"
    echo -e "${GREEN}                     版本:$bb"
    echo -e "${GREEN}                   云端版本:$bbs"
    echo -e "${GREEN}            作者：哔哩哔哩@万级的麦块"
    echo -e "${YELLOW}================================================${NC}"
}

normalize_path() {
    local path="$1"
    path=$(echo "$path" | sed 's|//*|/|g; s|^\./||; s|/$||')
    
    case "$path" in
        /*) ;;
        *) path="$(pwd)/$path" ;;
    esac
    
    case "$path" in
        /sdcard/*) echo "/storage/emulated/0/${path#/sdcard/}" ;;
        *) echo "$path" ;;
    esac
}

check_readable() {
    [ -r "$1" ] || { 
        echo -e "${RED}错误: 文件不可读或不存在: $1${NC}" >&2
        return 1
    }
}

check_space() {
    local input_file="$1"
    local output_file="$2"
    
    if ! input_size=$(du -k "$input_file" 2>/dev/null | awk '{print $1}'); then
        echo -e "${YELLOW}警告: 无法获取输入文件大小${NC}" >&2
        return 0
    fi
    
    local target_dir=$(dirname "$output_file")
    if ! available_space=$(df -k "$target_dir" 2>/dev/null | awk 'NR==2 {print $4}'); then
        echo -e "${YELLOW}警告: 无法检测磁盘空间${NC}" >&2
        return 0
    fi
    
    [ "$available_space" -ge "$((input_size * 3))" ] || {
        echo -e "${RED}错误：磁盘空间不足，需要至少 $((input_size * 3))KB 可用空间${NC}" >&2
        return 1
    }
}

octo_encrypt() {
    local input_file="$1"
    local output_file="$2"
    
    if ! script_content=$(cat "$input_file"); then
        echo -e "${RED}错误: 无法读取脚本内容${NC}" >&2
        return 1
    fi
    
    local len=${#script_content}
    [ "$len" -ge 8 ] || { 
        echo -e "${RED}错误: 脚本内容过短，至少需要8个字符${NC}" >&2
        return 1
    }
    
    local part_len=$(( (len + 7) / 8 ))
    
    {
        echo '#!/system/bin/sh'
        echo 'eval "$(echo "'$(echo -n "${script_content:0:$part_len}" | base64 -w 0)'" | base64 -d)\'
        echo '$(echo "'$(echo -n "${script_content:$part_len:$part_len}" | base64 -w 0)'" | base64 -d)\'
        echo '$(echo "'$(echo -n "${script_content:$((part_len * 2)):$part_len}" | base64 -w 0)'" | base64 -d)\'
        echo '$(echo "'$(echo -n "${script_content:$((part_len * 3)):$part_len}" | base64 -w 0)'" | base64 -d)\'
        echo '$(echo "'$(echo -n "${script_content:$((part_len * 4)):$part_len}" | base64 -w 0)'" | base64 -d)\'
        echo '$(echo "'$(echo -n "${script_content:$((part_len * 5)):$part_len}" | base64 -w 0)'" | base64 -d)\'
        echo '$(echo "'$(echo -n "${script_content:$((part_len * 6)):$part_len}" | base64 -w 0)'" | base64 -d)\'
        echo '$(echo "'$(echo -n "${script_content:$((part_len * 7))}" | base64 -w 0)'" | base64 -d)"'
    } > "$output_file" || {
        echo -e "${RED}错误: 无法写入输出文件${NC}" >&2
        return 1
    }
}

encrypt_file() {
    local input_file="$1"
    local output_file="$2"
    local encrypt_type="$3"
    
    case "$encrypt_type" in
        "base64")
            if ! e1=$(base64 -w 0 "$input_file" 2>/dev/null); then
                echo -e "${RED}Base64编码失败${NC}" >&2
                return 1
            fi
            echo '#!/system/bin/sh
d_script=$(echo "'"$e1"'" | base64 -d)
eval "$d_script"' > "$output_file"
            ;;
            
        "octo_base64")
            octo_encrypt "$input_file" "$output_file" || return 1
            ;;
            
        "binary")
            if ! e1=$(xxd -p "$input_file" 2>/dev/null | tr -d '\n'); then
                echo -e "${RED}二进制编码失败${NC}" >&2
                return 1
            fi
            echo '#!/system/bin/sh
d_script=$(echo "'"$e1"'" | xxd -r -p)
eval "$d_script"' > "$output_file"
            ;;
            
        "gzip")
            if ! e1=$(gzip -c "$input_file" 2>/dev/null | base64 -w 0); then
                echo -e "${RED}Gzip压缩失败${NC}" >&2
                return 1
            fi
            echo '#!/system/bin/sh
d_script=$(echo "'"$e1"'" | base64 -d | gunzip)
eval "$d_script"' > "$output_file"
            ;;
            
        "mixed")
            if ! e1=$(gzip -c "$input_file" 2>/dev/null | base64 -w 0 | xxd -p | tr -d '\n'); then
                echo -e "${RED}混合加密失败${NC}" >&2
                return 1
            fi
            echo '#!/system/bin/sh
d_script=$(echo "'"$e1"'" | xxd -r -p | base64 -d | gunzip)
eval "$d_script"' > "$output_file"
            ;;
    esac
    
    if ! chmod 755 "$output_file" 2>/dev/null; then
        echo -e "${YELLOW}警告: 无法设置执行权限${NC}" >&2
    fi
    echo -e "${GREEN}加密完成: ${output_file##*/}${NC}"
}

process_single() {
    local script_path="$1"
    
    [ -z "$script_path" ] && {
        echo -e "${YELLOW}请输入要加密的脚本路径:"
        echo -e "${BLUE}示例: /sdcard/scripts/myscript.sh${NC}"
        while read -r p; do
            p=$(normalize_path "$p")
            if check_readable "$p"; then
                script_path="$p"
                break
            fi
            echo -e "${RED}错误: 文件无效或不可读"
            echo -e "${YELLOW}请重新输入:${NC}"
        done
    } || {
        script_path=$(normalize_path "$1")
        check_readable "$script_path" || exit 1
    }

    echo -e "${YELLOW}输入保存目录 (留空使用原脚本所在目录): ${NC}"
    read -r dir
    [ -z "$dir" ] && dir=$(dirname "$script_path") || dir=$(normalize_path "$dir")

    if ! mkdir -p "$dir" 2>/dev/null; then
        echo -e "${RED}错误: 无法创建目录${NC}" >&2
        exit 1
    fi
    
    if [ ! -w "$dir" ]; then
        echo -e "${RED}错误: 无写入权限${NC}" >&2
        exit 1
    fi

    local default_name="${script_path##*/}"
    default_name="${default_name%.*}[加密].sh"
    
    echo -e "${YELLOW}输入文件名 (留空使用原文件名): ${NC}"
    read -r fname
    [ -z "$fname" ] && fname="$default_name"
    [ "${fname##*.}" != "sh" ] && fname="${fname%.*}.sh"

    local output="${dir%/}/$fname"
    check_space "$script_path" "$output" || exit 1

    encrypt_file "$script_path" "$output" "$encrypt_type" || exit 1
}

process_batch() {
    echo -e "${YELLOW}请输入文件夹路径: ${NC}"
    read -r folder_path
    folder_path=$(normalize_path "$folder_path")
    
    if [ ! -d "$folder_path" ]; then
        echo -e "${RED}错误: 该路径不是文件夹${NC}" >&2
        exit 1
    fi
    
    if [ ! -r "$folder_path" ]; then
        echo -e "${RED}错误: 无读取权限${NC}" >&2
        exit 1
    fi
    
    local success=0
    local fail=0
    
    echo -e "${YELLOW}正在扫描文件夹中的脚本文件...${NC}"
    find "$folder_path" -maxdepth 1 -type f \( -name "*.sh" -o -name "*.bash" \) | while read -r file; do
        [ -z "$file" ] && continue
        
        if echo "$file" | grep -q "\[已加密\]"; then
            echo -e "${YELLOW}跳过已加密文件: ${file##*/}${NC}"
            continue
        fi
        
        local output="${file%.*}[已加密].sh"
        
        if check_readable "$file" && check_space "$file" "$output"; then
            if encrypt_file "$file" "$output" "$encrypt_type"; then
                success=$((success + 1))
            else
                fail=$((fail + 1))
            fi
        else
            fail=$((fail + 1))
        fi
    done
    
    echo -e "${GREEN}批量加密完成: 成功 ${success} 个, 失败 ${fail} 个${NC}"
}

main() {
    check_commands
    get_cloud_data
    show_header
    
    if [ -n "$gg" ]; then
        gg=$(echo "$gg" | sed 's/<br>/\n/g')
        echo -e "${BS}$gg${NC}"
    fi

    gxbb=$(echo "$bb" | tr -d '.')
    gxbbs=$(echo "$bbs" | tr -d '.')

    if ! [[ "$gxbbs" =~ ^[0-9]+$ && "$gxbb" =~ ^[0-9]+$ ]]; then
        echo -e "${YELLOW}版本信息异常，跳过更新检查${NC}"
    else
        if [ "$gxbbs" -gt "$gxbb" ]; then
            mz="${mz}.sh"
            echo -e "${BLUE}正在更新至版本$bbs...${NC}"
            if curl -o "$mz" "$gxlj"; then
                chmod 755 "$mz"
                echo -e "${RED}更新完成，重启本脚本即可${NC}"
                exit 0
            else
                echo -e "${RED}更新失败，请检查网络或链接${NC}"
            fi
        fi
    fi

    echo -e "${RED}请选择加密方式:"
    echo -e "${BLUE}1. 普通Base64加密"
    echo -e "${BLUE}2. 变异Base64加密"
    echo -e "${BLUE}3. 二进制加密"
    echo -e "${BLUE}4. Gzip加密"
    echo -e "${BLUE}5. 混合加密${NC}"
    echo -e "${YELLOW}请输入序号: ${NC}"

    read -r choice
    case "$choice" in
        1) encrypt_type="base64";;
        2) encrypt_type="octo_base64";;
        3) encrypt_type="binary";;
        4) encrypt_type="gzip";;
        5) encrypt_type="mixed";;
        *) echo -e "${RED}无效选择${NC}"; exit 1;;
    esac

    echo -e "${YELLOW}是否启用批量加密？(y/n): ${NC}"
    read -r batch_mode

    case "$batch_mode" in
        y|Y) process_batch;;
        *) process_single "$1";;
    esac

    echo -e "${GREEN}操作完成${NC}"
    exit 0
}

main "$@"
