#!/bin/bash
# KSops 工程初始化与控制脚本
# 提供初始化、启动服务、关闭服务等功能

set -e

# 配置SSL证书权限，确保ksops用户可以访问
ensure_ksops_user_and_permissions() {
    local ssl_dir="/opt/ksops/nginx/ssl"

    # 如果SSL目录不存在，跳过权限设置
    if [ ! -d "$ssl_dir" ]; then
        log_warn "SSL证书目录不存在: $ssl_dir，跳过权限设置"
        return 0
    fi

    log_info "配置SSL证书权限，确保ksops用户可以访问..."

    # 检查ksops用户是否存在
    if ! id ksops >/dev/null 2>&1; then
        log_error "ksops用户不存在，无法设置SSL证书权限"
        log_error "请确保ksops服务包已安装并创建了ksops用户"
        return 1
    fi

    # 确保nginx-ssl组存在
    groupadd nginx-ssl 2>/dev/null || log_debug "nginx-ssl组已存在"

    # 将nginx用户添加到nginx-ssl组
    usermod -a -G nginx-ssl nginx 2>/dev/null || log_warn "添加nginx用户到nginx-ssl组失败"

    # 将ksops用户添加到nginx-ssl组
    if ! usermod -a -G nginx-ssl ksops 2>/dev/null; then
        log_error "添加ksops用户到nginx-ssl组失败"
        return 1
    fi
    log_info "✓ ksops用户已添加到nginx-ssl组"

    # 设置目录所有者和权限
    if ! chown -R nginx:nginx-ssl "$ssl_dir" 2>/dev/null; then
        log_error "无法设置SSL目录所有者"
        return 1
    fi

    # 私钥：所有者读写，nginx-ssl组读，其他无权限 (640)
    chmod 640 "$ssl_dir"/key.pem 2>/dev/null || log_warn "无法设置私钥权限"

    # 证书：所有者读写，nginx-ssl组读，其他无权限 (640)
    chmod 640 "$ssl_dir"/cert.pem 2>/dev/null || log_warn "无法设置证书权限"

    # 目录：所有者读写执行，nginx-ssl组读执行，其他无权限 (750)
    chmod 750 "$ssl_dir" 2>/dev/null || log_warn "无法设置目录权限"

    log_info "✓ SSL证书权限已配置完成"
    log_info "  私钥权限: 640 (nginx读写, nginx-ssl组读)"
    log_info "  证书权限: 640 (nginx读写, nginx-ssl组读)"
    log_info "  目录权限: 750 (nginx读写执行, nginx-ssl组读执行)"

    return 0
}

# 配置Prometheus目录权限，确保ksops用户可以读写
ensure_prometheus_permissions() {
    local prometheus_dir="/opt/ksops/prometheus"

    # 如果目录不存在，跳过权限设置
    if [ ! -d "$prometheus_dir" ]; then
        log_warn "Prometheus目录不存在: $prometheus_dir，跳过权限设置"
        return 0
    fi

    log_info "配置Prometheus目录权限，确保ksops用户可以读写..."

    # 检查ksops用户是否存在
    if ! id ksops >/dev/null 2>&1; then
        log_error "ksops用户不存在，无法设置Prometheus目录权限"
        log_error "请确保ksops服务包已安装并创建了ksops用户"
        return 1
    fi

    # 检查prometheus用户是否存在
    if ! id prometheus >/dev/null 2>&1; then
        log_warn "prometheus用户不存在，跳过Prometheus目录权限设置"
        return 0
    fi

    # 将ksops用户添加到prometheus组
    if ! usermod -a -G prometheus ksops 2>/dev/null; then
        log_error "添加ksops用户到prometheus组失败"
        return 1
    fi
    log_info "✓ ksops用户已添加到prometheus组"

    # 设置目录所有者和权限
    # 所有者：prometheus，组：prometheus，权限：775（组内用户可读写）
    if ! chown -R prometheus:prometheus "$prometheus_dir" 2>/dev/null; then
        log_error "无法设置Prometheus目录所有者"
        return 1
    fi

    # 目录权限：775（所有者读写执行，组读写执行，其他读执行）
    chmod 775 "$prometheus_dir" 2>/dev/null || log_warn "无法设置Prometheus目录权限"

    # 规则目录权限：775（ksops需要写入规则文件）
    if [ -d "$prometheus_dir/rules" ]; then
        chmod 775 "$prometheus_dir/rules" 2>/dev/null || log_warn "无法设置rules目录权限"
    fi

    # 配置文件权限：664（所有者读写，组读写，其他只读）
    if [ -f "$prometheus_dir/prometheus.yml" ]; then
        chmod 664 "$prometheus_dir/prometheus.yml" 2>/dev/null || log_warn "无法设置prometheus.yml权限"
    fi

    log_info "✓ Prometheus目录权限已配置完成"
    log_info "  目录权限: 775 (prometheus读写执行, prometheus组读写执行)"
    log_info "  rules目录权限: 775 (ksops用户可以写入规则文件)"

    return 0
}

# 脚本目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 使用绝对路径调用rsa_crypto.py，防止路径问题
RSA_CRYPTO_SCRIPT="/opt/ksops/script/rsa_crypto.py"

# 配置路径
NGINX_SSL_DIR="/opt/ksops/nginx/ssl"
NGINX_CONF="/opt/ksops/nginx/nginx.conf"
NGINX_SERVICE="nginx-ksops.service"
PROMETHEUS_SERVICE="prometheus-ksops.service"
ALERTMANAGER_SERVICE="alertmanager-ksops.service"
INTELLIGENCE_SERVICE="ksops-intelligence.service"
KSOPS_WEBSERVER_SERVICE="ksops.service"

# PIN 码临时文件
# 使用 /opt/ksops/nginx/ 目录，确保 nginx 用户可以访问
PIN_TEMP_DIR="/opt/ksops/nginx"
PIN_TEMP_FILE="${PIN_TEMP_DIR}/.nginx-pin.$$"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_debug() { echo -e "${BLUE}[DEBUG]${NC} $1"; }

# 清理函数：删除 PIN 码临时文件
cleanup_pin_file() {
    if [ -n "$PIN_TEMP_FILE" ] && [ -f "$PIN_TEMP_FILE" ]; then
        rm -f "$PIN_TEMP_FILE"
        log_debug "已清理 PIN 码临时文件: $PIN_TEMP_FILE"
    fi
}

# 清理函数：删除所有旧的备份文件和 PIN 码临时文件
cleanup_old_files() {
    local nginx_dir="/opt/ksops/nginx"
    
    # 删除所有 nginx.conf 备份文件
    if [ -d "$nginx_dir" ]; then
        local backup_count=$(find "$nginx_dir" -maxdepth 1 -name "nginx.conf.backup.*" -type f 2>/dev/null | wc -l)
        if [ "$backup_count" -gt 0 ]; then
            find "$nginx_dir" -maxdepth 1 -name "nginx.conf.backup.*" -type f -delete 2>/dev/null
            log_debug "已清理 $backup_count 个 nginx.conf 备份文件"
        fi
        
        # 删除所有 PIN 码临时文件
        local pin_count=$(find "$nginx_dir" -maxdepth 1 -name ".nginx-pin.*" -type f 2>/dev/null | wc -l)
        if [ "$pin_count" -gt 0 ]; then
            find "$nginx_dir" -maxdepth 1 -name ".nginx-pin.*" -type f -delete 2>/dev/null
            log_debug "已清理 $pin_count 个 PIN 码临时文件"
        fi
        
        # 删除所有 .htpasswd 备份文件
        local htpasswd_backup_count=$(find "$nginx_dir" -maxdepth 1 -name ".htpasswd.backup.*" -type f 2>/dev/null | wc -l)
        if [ "$htpasswd_backup_count" -gt 0 ]; then
            find "$nginx_dir" -maxdepth 1 -name ".htpasswd.backup.*" -type f -delete 2>/dev/null
            log_debug "已清理 $htpasswd_backup_count 个 .htpasswd 备份文件"
        fi
    fi
}

# 清理函数：确保脚本异常退出时删除临时文件
# 注意：不设置 EXIT trap，因为我们需要在 systemd 启动服务后再清理
# INT 信号：用户按 Ctrl+C 时触发
# TERM 信号：进程被终止时触发
cleanup_on_error() {
    # 清理 PIN 文件（使用全局变量 PIN_TEMP_FILE）
    # 注意：即使 PIN_TEMP_FILE 可能还没有设置，cleanup_pin_file 函数会检查
    cleanup_pin_file
    
    # 清理可能存在的备份文件（使用进程ID匹配）
    # 这样可以清理当前进程创建的所有备份文件
    local nginx_dir="/opt/ksops/nginx"
    if [ -d "$nginx_dir" ] && [ -n "$$" ]; then
        find "$nginx_dir" -maxdepth 1 -name "nginx.conf.backup.$$" -type f -delete 2>/dev/null || true
        # 也清理可能残留的 PIN 文件（使用进程ID匹配）
        find "$nginx_dir" -maxdepth 1 -name ".nginx-pin.$$" -type f -delete 2>/dev/null || true
    fi
}
# 捕获中断信号（用户按 Ctrl+C）和终止信号
# 当用户按 Ctrl+C 时，会立即触发此清理函数
trap cleanup_on_error INT TERM

# 获取 PIN 码（保存在变量中，方便其他地方使用）
get_pin_code() {
    local pin_var_name="${1:-KSops_PIN}"
    local prompt="${2:-请输入 PIN 码（用于解密 SSL 私钥）: }"
    
    # 如果已经设置了 PIN 码变量，直接使用
    if [ -n "${!pin_var_name}" ]; then
        eval "echo \${$pin_var_name}"
        return 0
    fi
    
    # 否则提示用户输入
    while true; do
        read -s -p "$prompt" pin1
        echo ""
        if [ -z "$pin1" ]; then
            log_error "PIN 不能为空，请重新输入。"
            continue
        fi
        if [ ${#pin1} -lt 6 ]; then
            log_warn "PIN 长度至少为 6 位，建议使用强密码。"
            read -p "是否继续使用此 PIN？(y/n): " confirm
            if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
                continue
            fi
        fi
        read -s -p "请再次输入 PIN 码: " pin2
        echo ""
        if [ "$pin1" = "$pin2" ]; then
            # 保存到变量
            eval "$pin_var_name='$pin1'"
            echo "$pin1"
            return 0
        else
            log_error "两次输入不一致，请重试。"
        fi
    done
}

# 保存 PIN 码到临时文件（权限 600）
save_pin_to_temp_file() {
    local pin="$1"
    local temp_file="$2"
    
    if [ -z "$pin" ] || [ -z "$temp_file" ]; then
        log_error "PIN 码或临时文件路径为空"
        return 1
    fi
    
    # 创建临时文件目录（如果不存在）
    local temp_dir=$(dirname "$temp_file")
    mkdir -p "$temp_dir"
    
    # 使用 printf 而不是 echo，避免自动添加换行符
    # nginx 的 ssl_password_file 需要密码明文，不能有多余的换行符
    printf "%s" "$pin" > "$temp_file"
    
    # 设置文件权限和所有者
    # 确保 nginx 用户可以读取（如果 nginx 用户存在）
    if id nginx >/dev/null 2>&1; then
        # 设置文件所有者为 nginx:nginx
        chown nginx:nginx "$temp_file" 2>/dev/null || chown root:root "$temp_file"
        # 文件权限：600（只有所有者可读写，nginx 用户作为所有者可以读取）
        chmod 600 "$temp_file"
        # 目录权限：755（nginx 用户需要能够访问目录）
        # 目录所有者保持为 root:root，但权限允许 nginx 用户访问
        chown root:root "$temp_dir" 2>/dev/null || true
        chmod 755 "$temp_dir"
    else
        # 如果没有 nginx 用户，使用 root
        chown root:root "$temp_file" 2>/dev/null || true
        chmod 600 "$temp_file"
        chmod 755 "$temp_dir" 2>/dev/null || true
    fi
    
    #log_debug "PIN 码已保存到临时文件: $temp_file (权限 600)"
    return 0
}

# 获取本机 IP 地址
get_ip_address() {
    local ip_address
    
    # 优先使用默认路由网卡的 IP
    ip_address=$(ip route get 8.8.8.8 2>/dev/null | awk '{print $7; exit}' | grep -v '^$')
    
    if [ -z "$ip_address" ]; then
        # 如果无法获取，使用 hostname -I 的第一个 IP
        ip_address=$(hostname -I | awk '{print $1}' | grep -v '^$')
    fi
    
    if [ -z "$ip_address" ]; then
        # 最后的备选方案：使用 localhost
        ip_address="127.0.0.1"
    fi
    
    echo "$ip_address"
}

# 初始化功能：生成 SSL 证书
init_ssl_cert() {
    log_info "开始初始化 SSL 证书..."
    
    # 检查证书是否已存在
    if [ -f "${NGINX_SSL_DIR}/cert.pem" ] && [ -f "${NGINX_SSL_DIR}/key.pem" ]; then
        log_warn "SSL 证书已存在: ${NGINX_SSL_DIR}/cert.pem"
        read -p "是否重新生成证书？(y/n): " confirm
        if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
            log_info "跳过证书生成"
            # 确保证书已复制到 data_col_template/ssl 目录
            local data_col_ssl_dir="/opt/ksops/data_col_template/ssl"
            if [ ! -f "${data_col_ssl_dir}/server.crt" ]; then
                mkdir -p "$data_col_ssl_dir"
                cp "${NGINX_SSL_DIR}/cert.pem" "${data_col_ssl_dir}/server.crt"
                chmod 644 "${data_col_ssl_dir}/server.crt"
                log_info "✓ 证书已复制到: ${data_col_ssl_dir}/server.crt"
            fi
            return 0
        fi
        # 备份现有证书
        local backup_dir="${NGINX_SSL_DIR}/backup_$(date +%Y%m%d_%H%M%S)"
        mkdir -p "$backup_dir"
        cp "${NGINX_SSL_DIR}/cert.pem" "$backup_dir/" 2>/dev/null || true
        cp "${NGINX_SSL_DIR}/key.pem" "$backup_dir/" 2>/dev/null || true
        log_info "已备份现有证书到: $backup_dir"
    fi
    
    # 创建 SSL 目录
    mkdir -p "$NGINX_SSL_DIR"
    
    # 获取 IP 地址
    local ip_address=$(get_ip_address)
    log_info "检测到 IP 地址: $ip_address"
    
    # 调用 rsa_crypto.py 生成证书（rsa_crypto.py 会自己处理 PIN 码输入）
    log_info "正在生成受 PIN 保护的 SSL 证书..."
    log_info "提示: rsa_crypto.py 将要求您输入 PIN 码（用于加密私钥）"
    if ! python3 "$RSA_CRYPTO_SCRIPT" generate-ssl-cert \
        --privkey "${NGINX_SSL_DIR}/key.pem" \
        --cert "${NGINX_SSL_DIR}/cert.pem" \
        --cn "$ip_address" \
        --days 3650 \
        --country "CN" \
        --state "Beijing" \
        --city "Beijing" \
        --org "KSOPS"; then
        log_error "SSL 证书生成失败"
        return 1
    fi
    
    # 设置证书文件权限（让nginx-ssl组的用户也能访问）
    # 首先确保nginx-ssl组存在
    groupadd nginx-ssl 2>/dev/null || log_warn "nginx-ssl组已存在或创建失败"

    # 将nginx用户添加到nginx-ssl组
    usermod -a -G nginx-ssl nginx 2>/dev/null || log_warn "添加nginx用户到nginx-ssl组失败"

    # 将ksops用户添加到nginx-ssl组
    if ! id ksops >/dev/null 2>&1; then
        log_warn "ksops用户不存在，SSL证书权限可能无法正确设置"
        log_warn "请确保ksops服务包已安装并创建了ksops用户"
    else
        usermod -a -G nginx-ssl ksops 2>/dev/null || log_warn "添加ksops用户到nginx-ssl组失败"
    fi

    # 设置目录所有者和权限
    chown -R nginx:nginx-ssl "$NGINX_SSL_DIR" 2>/dev/null || {
        log_warn "无法设置SSL目录所有者，使用root:root"
        chown -R root:root "$NGINX_SSL_DIR" 2>/dev/null || true
    }

    # 私钥：所有者读写，nginx-ssl组读，其他无权限 (640)
    # 注意：ksops服务需要读取私钥用于TLS连接
    chmod 640 "${NGINX_SSL_DIR}/key.pem" 2>/dev/null || log_warn "无法设置私钥权限"

    # 证书：所有者读写，nginx-ssl组读，其他无权限 (640)
    chmod 640 "${NGINX_SSL_DIR}/cert.pem" 2>/dev/null || log_warn "无法设置证书权限"

    # 目录：所有者读写执行，nginx-ssl组读执行，其他无权限 (750)
    chmod 750 "$NGINX_SSL_DIR" 2>/dev/null || log_warn "无法设置目录权限"

    log_info "✓ SSL证书权限已设置完成"
    
    # 复制证书到 data_col_template/ssl 目录
    local data_col_ssl_dir="/opt/ksops/data_col_template/ssl"
    mkdir -p "$data_col_ssl_dir"
    cp "${NGINX_SSL_DIR}/cert.pem" "${data_col_ssl_dir}/server.crt"
    chmod 644 "${data_col_ssl_dir}/server.crt"
    log_info "✓ 证书已复制到: ${data_col_ssl_dir}/server.crt"
    
    log_info "✓ SSL 证书已生成: ${NGINX_SSL_DIR}/cert.pem"
    log_info "  证书 IP 地址: $ip_address"
    log_info "  私钥文件: ${NGINX_SSL_DIR}/key.pem (已加密，需要 PIN 码)"
    
    return 0
}

# 初始化功能：配置 HTTP Basic 认证
init_basic_auth() {
    local htpasswd_file="/opt/ksops/nginx/.htpasswd"
    
    log_info "开始配置 HTTP Basic 认证..."
    
    # 检查文件是否已存在
    if [ -f "$htpasswd_file" ]; then
        log_warn "HTTP Basic 认证文件已存在: $htpasswd_file"
        read -p "是否重新配置认证信息？(y/n): " confirm
        if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
            log_info "跳过 HTTP Basic 认证配置"
            return 0
        fi
        # 备份现有文件
        local backup_file="${htpasswd_file}.backup.$(date +%Y%m%d_%H%M%S)"
        cp "$htpasswd_file" "$backup_file" 2>/dev/null || true
        log_info "已备份现有认证文件到: $backup_file"
    fi
    
    # 获取用户名
    local username=""
    while [ -z "$username" ]; do
        read -p "请输入 HTTPS 认证用户名: " username
        if [ -z "$username" ]; then
            log_error "用户名不能为空，请重新输入。"
        fi
        # 检查用户名是否包含非法字符（htpasswd 不支持冒号和空格）
        # 使用更明确的方式检查：冒号或空格字符
        if echo "$username" | grep -qE '[:\ ]'; then
            log_error "用户名不能包含冒号或空格，请重新输入。"
            username=""
        fi
    done
    
    # 密码验证函数：长度>=8位，包含数字和字母
    validate_password() {
        local pwd="$1"
        
        # 检查长度是否>=8位
        if [ ${#pwd} -lt 8 ]; then
            log_error "密码长度至少为8位，当前长度为 ${#pwd} 位"
            return 1
        fi
        
        # 检查是否包含数字
        if ! echo "$pwd" | grep -q '[0-9]'; then
            log_error "密码必须包含至少一个数字"
            return 1
        fi
        
        # 检查是否包含字母（大小写均可）
        if ! echo "$pwd" | grep -q '[a-zA-Z]'; then
            log_error "密码必须包含至少一个字母"
            return 1
        fi
        
        return 0
    }

    # 获取密码
    local password=""
    local password_confirm=""
    while true; do
        read -s -p "请输入密码（至少8位，包含数字和字母）: " password
        echo ""
        if [ -z "$password" ]; then
            log_error "密码不能为空，请重新输入。"
            continue
        fi
        
        # 验证密码格式
        if ! validate_password "$password"; then
            continue
        fi
        
        read -s -p "请再次输入密码: " password_confirm
        echo ""
        if [ "$password" = "$password_confirm" ]; then
            break
        else
            log_error "两次输入的密码不一致，请重试。"
        fi
    done
    
    # 创建目录（如果不存在）
    mkdir -p "$(dirname "$htpasswd_file")"
    
    # 尝试使用 htpasswd 命令（如果可用）
    if command -v htpasswd >/dev/null 2>&1; then
        log_info "使用 htpasswd 工具生成认证文件..."
        # 如果文件已存在，删除旧文件
        if [ -f "$htpasswd_file" ]; then
            rm -f "$htpasswd_file"
        fi
        # 使用 -b 参数从命令行读取密码，-c 创建新文件
        # -b 参数：从命令行读取密码（非交互式）
        # -c 参数：创建新文件（如果文件已存在则覆盖）
        htpasswd -c -b "$htpasswd_file" "$username" "$password" 2>/dev/null
        if [ $? -eq 0 ]; then
            log_info "✓ 使用 htpasswd 工具生成认证文件成功"
        else
            log_warn "htpasswd 工具执行失败，尝试使用 openssl..."
            # 如果 htpasswd 失败，使用 openssl
            local encrypted_password=$(openssl passwd -apr1 "$password" 2>/dev/null)
            if [ -n "$encrypted_password" ]; then
                echo "${username}:${encrypted_password}" > "$htpasswd_file"
                log_info "✓ 使用 openssl 生成认证文件成功"
            else
                log_error "无法生成认证文件，请检查系统是否安装了 httpd-tools 或 openssl"
                return 1
            fi
        fi
    else
        # 如果没有 htpasswd，使用 openssl
        log_info "未找到 htpasswd 工具，使用 openssl 生成认证文件..."
        local encrypted_password=$(openssl passwd -apr1 "$password" 2>/dev/null)
        if [ -n "$encrypted_password" ]; then
            echo "${username}:${encrypted_password}" > "$htpasswd_file"
            log_info "✓ 使用 openssl 生成认证文件成功"
        else
            log_error "无法生成认证文件，请安装 httpd-tools (yum install httpd-tools) 或确保 openssl 可用"
            return 1
        fi
    fi
    
    # 设置文件权限和所有者
    chmod 644 "$htpasswd_file"
    chown nginx:nginx "$htpasswd_file" 2>/dev/null || chown root:root "$htpasswd_file"
    
    log_info "✓ HTTP Basic 认证配置完成"
    log_info "  认证文件: $htpasswd_file"
    log_info "  用户名: $username"
    
    # 清理内存中的密码
    unset password
    unset password_confirm
    
    return 0
}

# 初始化功能：完整初始化
init() {
    log_info "开始初始化 KSops 工程..."
    
    # 清理旧的备份文件和临时文件
    cleanup_old_files
    
    # 初始化 SSL 证书
    init_ssl_cert
    
    # 配置 HTTP Basic 认证
    init_basic_auth

    /opt/ksops/ksops-server/script/init-database.sh || log_warn "初始化数据库失败"
    
    log_info "✓ KSops 工程初始化完成"
}

# 启动 nginx 服务（需要 PIN 码）
start_nginx() {
    # 设置局部变量，用于错误清理
    local nginx_conf_backup=""
    local pin_file_created=false
    
    log_info "启动 nginx 服务..."
    
    # 清理旧的备份文件和 PIN 码临时文件
    cleanup_old_files
    
    # 检查服务是否已在运行（如果正在运行，需要先停止以便重新配置）
    if systemctl is-active --quiet "$NGINX_SERVICE" 2>/dev/null; then
        log_info "nginx 服务正在运行，先停止服务以便重新配置..."
        systemctl stop "$NGINX_SERVICE" || log_warn "停止 nginx 服务失败"
        sleep 1
    fi
    
    # 检查证书是否存在
    if [ ! -f "${NGINX_SSL_DIR}/cert.pem" ] || [ ! -f "${NGINX_SSL_DIR}/key.pem" ]; then
        log_error "SSL 证书不存在，请先运行初始化: $0 init"
        return 1
    fi
    
    # 检查私钥是否加密（检查是否包含 "ENCRYPTED PRIVATE KEY" 或传统的 "Proc-Type: 4,ENCRYPTED"）
    if grep -q "ENCRYPTED PRIVATE KEY\|Proc-Type.*ENCRYPTED" "${NGINX_SSL_DIR}/key.pem" 2>/dev/null; then
        log_info "检测到私钥已加密，需要 PIN 码"
        
        # 获取 PIN 码
        local pin=$(get_pin_code "KSops_PIN" "请输入 PIN 码（用于解密 SSL 私钥）: ")
        
        # 保存 PIN 码到临时文件
        save_pin_to_temp_file "$pin" "$PIN_TEMP_FILE"
        pin_file_created=true  # 标记 PIN 文件已创建
        
        # 确保 nginx 用户可以读取密码文件（如果 nginx 用户存在）
        if id nginx >/dev/null 2>&1; then
            chown nginx:nginx "$PIN_TEMP_FILE" 2>/dev/null || true
        fi
        
        # 备份原始配置文件
        nginx_conf_backup="${NGINX_CONF}.backup.$$"
        cp "$NGINX_CONF" "$nginx_conf_backup"
        
        # 设置局部清理函数，在函数退出时清理
        local_cleanup() {
            if [ -n "$nginx_conf_backup" ] && [ -f "$nginx_conf_backup" ]; then
                # 只有在错误情况下才恢复配置（成功时会手动删除备份）
                if [ "$1" != "success" ]; then
                    mv "$nginx_conf_backup" "$NGINX_CONF" 2>/dev/null || true
                fi
                rm -f "$nginx_conf_backup" 2>/dev/null || true
            fi
        }
        # 在函数退出时调用清理（包括正常退出和错误退出）
        trap "local_cleanup" RETURN
        
        # 检查配置文件中是否已有 ssl_password_file
        local has_password_file=false
        if grep -q "ssl_password_file" "$NGINX_CONF"; then
            has_password_file=true
            # 更新现有的 ssl_password_file 行
            sed -i "s|ssl_password_file.*|ssl_password_file ${PIN_TEMP_FILE};|" "$NGINX_CONF"
        else
            # 在 server 块中添加 ssl_password_file（在 ssl_certificate_key 之后）
            sed -i "/ssl_certificate_key/a\\    ssl_password_file ${PIN_TEMP_FILE};" "$NGINX_CONF"
        fi
        
        # 测试 nginx 配置（使用详细输出以便调试）
        log_info "测试 nginx 配置..."
        local nginx_test_output=$(nginx -t -c "$NGINX_CONF" 2>&1)
        local nginx_test_status=$?
        if [ $nginx_test_status -ne 0 ]; then
            log_error "nginx 配置测试失败:"
            echo "$nginx_test_output" | while IFS= read -r line; do
                log_error "  $line"
            done
            log_error "恢复原始配置"
            # 清理会在 RETURN trap 中自动执行
            return 1
        fi
        log_info "✓ nginx 配置测试通过"
        
        # 启动 nginx
        # 注意：systemd 服务的 ExecStartPre 也会测试配置，需要确保密码文件在启动时可用
        log_info "启动 nginx 服务..."
        
        # 再次确保密码文件和目录权限正确（systemd 启动时可能需要）
        local temp_dir=$(dirname "$PIN_TEMP_FILE")
        if id nginx >/dev/null 2>&1; then
            # 确保目录存在且权限正确
            mkdir -p "$temp_dir"
            chown root:root "$temp_dir" 2>/dev/null || true
            chmod 755 "$temp_dir"
            # 确保文件权限和所有者正确（600 权限，nginx 用户作为所有者可以读取）
            chown nginx:nginx "$PIN_TEMP_FILE" 2>/dev/null || chown root:root "$PIN_TEMP_FILE"
            chmod 600 "$PIN_TEMP_FILE"
        else
            chmod 600 "$PIN_TEMP_FILE"
            chown root:root "$PIN_TEMP_FILE" 2>/dev/null || true
        fi
        
        # 验证文件是否可读（用于调试）
        if [ ! -r "$PIN_TEMP_FILE" ]; then
            log_error "密码文件不可读: $PIN_TEMP_FILE"
            log_error "文件权限: $(ls -l "$PIN_TEMP_FILE" 2>/dev/null || echo '文件不存在')"
            # 恢复原始配置
            mv "$nginx_conf_backup" "$NGINX_CONF" 2>/dev/null || true
            cleanup_pin_file
            return 1
        fi
        
        # 使用 systemctl start 启动服务（会触发 ExecStartPre 配置测试）
        # 注意：不要重定向输出，以便看到错误信息
        log_info "正在启动 nginx 服务（systemd 会先测试配置）..."
        systemctl start "$NGINX_SERVICE" 2>&1
        local start_status=$?
        
        # 等待一下，让服务有时间启动
        sleep 2
        
        # 检查 nginx 是否成功启动
        if [ $start_status -eq 0 ] && systemctl is-active --quiet "$NGINX_SERVICE" 2>/dev/null; then
                log_info "✓ nginx 服务已启动"
                
                # 为了安全，我们删除 ssl_password_file 行，因为 PIN 文件已经删除
                sed -i "\|ssl_password_file.*\.nginx-pin\.$$|d" "$NGINX_CONF"
                
                # 标记为成功，清理函数不会恢复配置
                pin_file_created=false  # PIN 文件已清理
                rm -f "$nginx_conf_backup"
                nginx_conf_backup=""  # 清空变量，避免清理函数再次处理
                
                # 取消 RETURN trap（因为已经手动清理完成）
                trap - RETURN
                
                return 0
        else
            log_error "nginx 服务启动失败"
            # 查看服务状态以获取更多错误信息
            log_error "服务状态:"
            systemctl status "$NGINX_SERVICE" --no-pager -l | head -20 || true
            log_error "恢复原始配置"
            # 清理会在 RETURN trap 中自动执行
            return 1
        fi
    else
        # 私钥未加密，直接启动
        log_info "私钥未加密，直接启动 nginx..."
        if systemctl start "$NGINX_SERVICE"; then
            log_info "✓ nginx 服务已启动"
            return 0
        else
            log_error "nginx 服务启动失败"
            return 1
        fi
    fi
}

# 启动所有服务
start() {
    log_info "启动 KSops 服务..."

    # 设置异常退出时的清理函数
    # 注意：此trap会在脚本异常退出时自动执行，确保PIN文件被清理
    cleanup_on_exit() {
        if [ -f "$PIN_TEMP_FILE" ]; then
            cleanup_pin_file
            log_warn "由于异常退出，已清理 PIN 码临时文件"
        fi
    }
    trap cleanup_on_exit EXIT

    # 启动 Prometheus
    if systemctl is-enabled --quiet "$PROMETHEUS_SERVICE" 2>/dev/null; then
        log_info "启动 Prometheus 服务..."
        systemctl start "$PROMETHEUS_SERVICE" || log_warn "Prometheus 启动失败"
    fi
    
    # 启动 Alertmanager
    if systemctl is-enabled --quiet "$ALERTMANAGER_SERVICE" 2>/dev/null; then
        log_info "启动 Alertmanager 服务..."
        systemctl start "$ALERTMANAGER_SERVICE" || log_warn "Alertmanager 启动失败"
    fi

    #启动  ksops-intelligence
    if systemctl is-enabled --quiet "$INTELLIGENCE_SERVICE" 2>/dev/null; then
        log_info "启动 ksops-intelligence 服务..."
        systemctl start "$INTELLIGENCE_SERVICE" || log_warn "ksops-intelligence 启动失败"
    fi

    # 启动 nginx（最后启动，因为它依赖前面的服务）
    # 注意：如果start_nginx失败，EXIT trap会自动清理PIN文件（如果已创建）
    if ! start_nginx; then
        log_error "nginx 启动失败，终止启动流程"
        return 1
    fi

    # 配置SSL证书权限，确保ksops用户可以访问
    ensure_ksops_user_and_permissions || log_warn "SSL证书权限设置失败，ksops服务可能无法访问证书"

    # 配置Prometheus目录权限，确保ksops用户可以读写
    ensure_prometheus_permissions || log_warn "Prometheus目录权限设置失败，ksops服务可能无法写入规则文件"

    # 执行ksops-start（使用PIN码临时文件）
    log_info "启动ksops服务..."
    ksops-start -fp $PIN_TEMP_FILE
    local ksops_start_status=$?

    # 无论ksops-start成功还是失败，都要删除PIN码临时文件
    if [ -f "$PIN_TEMP_FILE" ]; then
        cleanup_pin_file
        log_info "✓ 已删除 PIN 码临时文件"
    fi

    # 清除异常退出时的清理trap，因为已经成功清理PIN文件
    trap - EXIT

    # 检查ksops-start的执行结果
    if [ $ksops_start_status -ne 0 ]; then
        log_error "ksops-start 执行失败（退出码: $ksops_start_status）"
        log_error "请检查ksops服务日志以获取详细信息"
        return 1
    fi

    log_info "✓ 所有服务启动完成"
}

# 停止所有服务
stop() {
    log_info "停止 KSops 服务..."
    
    # 停止 nginx
    if systemctl is-active --quiet "$NGINX_SERVICE" 2>/dev/null; then
        log_info "停止 nginx 服务..."
        systemctl stop "$NGINX_SERVICE" || log_warn "nginx 停止失败"
    fi
    
    # 停止 Alertmanager
    if systemctl is-active --quiet "$ALERTMANAGER_SERVICE" 2>/dev/null; then
        log_info "停止 Alertmanager 服务..."
        systemctl stop "$ALERTMANAGER_SERVICE" || log_warn "Alertmanager 停止失败"
    fi
    
    # 停止 Prometheus
    if systemctl is-active --quiet "$PROMETHEUS_SERVICE" 2>/dev/null; then
        log_info "停止 Prometheus 服务..."
        systemctl stop "$PROMETHEUS_SERVICE" || log_warn "Prometheus 停止失败"
    fi

    if systemctl is-active --quiet "$KSOPS_WEBSERVER_SERVICE" 2>/dev/null; then
        log_info "停止 ksops 服务..."
        systemctl stop "$KSOPS_WEBSERVER_SERVICE" || log_warn "ksops 停止失败"
    fi
    
    log_info "✓ 所有服务已停止"
}

# 重启服务
restart() {
    log_info "重启 KSops 服务..."
    stop
    sleep 2
    start
}

# 查看服务状态
status() {
    log_info "KSops 服务状态:"
    echo ""
    
    echo "Prometheus:"
    systemctl status "$PROMETHEUS_SERVICE" --no-pager -l || echo "  未安装或未启用"
    echo ""
    
    echo "Alertmanager:"
    systemctl status "$ALERTMANAGER_SERVICE" --no-pager -l || echo "  未安装或未启用"
    echo ""
    
    echo "Nginx:"
    systemctl status "$NGINX_SERVICE" --no-pager -l || echo "  未安装或未启用"
}

# 显示使用帮助
usage() {
    cat <<EOF
KSops 工程初始化与控制脚本

用法: $0 <command> [options]

命令:
  init        初始化工程（生成 SSL 证书等）
  start       启动所有服务
  stop        停止所有服务
  restart     重启所有服务
  status      查看服务状态
  help        显示此帮助信息

示例:
  $0 init              # 初始化工程
  $0 start             # 启动所有服务
  $0 stop              # 停止所有服务
  $0 restart           # 重启所有服务
  $0 status            # 查看服务状态

说明:
  - 初始化时会生成受 PIN 保护的 SSL 证书
  - 启动 nginx 时，如果私钥已加密，需要输入 PIN 码
  - PIN 码会临时保存到 /tmp/ksops-nginx-pin.* 文件（权限 600），nginx 启动后自动删除

EOF
}

# 主函数
main() {
    case "${1:-}" in
        init)
            init
            ;;
        start)
            start
            ;;
        stop)
            stop
            ;;
        restart)
            restart
            ;;
        status)
            status
            ;;
        help|--help|-h)
            usage
            ;;
        *)
            log_error "未知命令: ${1:-}"
            echo ""
            usage
            exit 1
            ;;
    esac
}

# 执行主函数
main "$@"
