#!/bin/bash
################################################################################
# 54_file_permission_check.sh — 文件权限检测
# 功能: 检查关键文件/目录的权限是否正确
# 参考: FilePermission.psm1
# 日期: 2026-07-22
# 说明: 只检测不修复，发现权限异常标记为警告
################################################################################

# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"

# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
    source "$LIB_DIR/lib/config.sh"
else
    echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
    exit 1
fi

if [ -f "$LIB_DIR/lib/common.sh" ]; then
    source "$LIB_DIR/lib/common.sh"
else
    echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
    exit 1
fi

# ==================== 平台类型识别 ====================

detect_platform_type() {
    [ -d "/data/services" ] && echo "new" || echo "old"
}

# ==================== 权限检查逻辑 ====================

# 检查单个文件权限
# 返回: 0=正常, 1=异常
check_file_permission() {
    local file="$1"
    local expect_exec="$2"  # "yes" or "no"

    [ ! -e "$file" ] && return 0  # 文件不存在，跳过（不计入异常）

    local perm
    # 兼容 GNU stat 和 BSD stat
    perm=$(stat -c '%a' "$file" 2>/dev/null || stat -f '%Lp' "$file" 2>/dev/null)

    if [ -z "$perm" ]; then
        return 0  # 无法获取权限，跳过
    fi

    local is_exec=0
    [ $((perm & 0111)) -ne 0 ] && is_exec=1

    if [ "$expect_exec" = "yes" ] && [ $is_exec -eq 0 ]; then
        # 应可执行但不可执行
        return 1
    elif [ "$expect_exec" = "no" ] && [ $is_exec -ne 0 ]; then
        # 应不可执行但可执行
        return 1
    fi

    return 0
}

# ==================== 主检测流程 ====================

main() {
    log_info "开始文件权限检测..."

    set +e

    local platform_type
    platform_type=$(detect_platform_type)

    local total_checks=0
    local wrong_count=0
    local wrong_list=""

    # 定义检查路径（格式: path:expect_exec）
    # yes=应可执行, no=应不可执行
    local -a check_paths

    if [ "$platform_type" = "new" ]; then
        check_paths=(
            "/data/services/api/start.sh:yes"
            "/data/services/api/auth/auth-sso-auth/run.sh:yes"
            "/data/services/api/auth/auth-sso-gateway/run.sh:yes"
            "/data/services/api/auth/auth-sso-system/run.sh:yes"
            "/data/services/api/java-meeting/java-meeting2.0/run.sh:yes"
            "/data/services/api/java-meeting/java-meeting-extapi/run.sh:yes"
            "/data/services/api/java-meeting/java-message-scheduling/run.sh:yes"
            "/data/services/api/java-meeting/java-mqtt/run.sh:yes"
            "/data/services/api/java-meeting/java-quartz/run.sh:yes"
            "/data/third_party/paperless/run.sh:yes"
            "/data/third_party/paperless/start.sh:yes"
            "/etc/rc.d/rc.local:yes"
        )
    else
        check_paths=(
            "/var/www/java/start.sh:yes"
            "/var/www/java/api-java-meeting2.0/run.sh:yes"
            "/var/www/java/external-meeting-api/run.sh:yes"
            "/var/www/html/start.sh:yes"
            "/var/www/paperless/run.sh:yes"
            "/var/www/paperless/start.sh:yes"
            "/etc/rc.d/rc.local:yes"
        )
    fi

    for entry in "${check_paths[@]}"; do
        local path expect_exec
        path="${entry%:*}"
        expect_exec="${entry#*:}"

        total_checks=$((total_checks + 1))

        if ! check_file_permission "$path" "$expect_exec"; then
            wrong_count=$((wrong_count + 1))
            local escaped_path
            escaped_path=$(echo "$path" | sed 's/"/\\"/g')
            [ -n "$wrong_list" ] && wrong_list="${wrong_list},"
            wrong_list="${wrong_list}{\"path\":\"${escaped_path}\",\"expected_exec\":\"${expect_exec}\"}"
        fi
    done

    # 输出结果
    if [ "$wrong_count" -eq 0 ]; then
        output_result "FILE_PERM_STATUS" "OK"
        output_result "FILE_PERM_STATUS_LEVEL" "正常"
    else
        output_result "FILE_PERM_STATUS" "WARN"
        output_result "FILE_PERM_STATUS_LEVEL" "警告"
    fi

    output_result "FILE_PERM_TOTAL_CHECKS" "$total_checks"
    output_result "FILE_PERM_WRONG_COUNT" "$wrong_count"

    if [ -n "$wrong_list" ]; then
        output_result "FILE_PERM_WRONG_LIST" "[${wrong_list}]"
    else
        output_result "FILE_PERM_WRONG_LIST" "[]"
    fi

    log_info "文件权限检测完成"
}

main