#!/bin/bash

# SSL证书同步脚本
# 将证书从Docker卷复制到1Panel统一的SSL目录

# 设置颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 源目录 - Docker卷中的证书
SOURCE_DIR="/var/lib/docker/volumes/ssl_cert/_data"

# 目标目录 - 1Panel统一的SSL目录
TARGET_DIR="/opt/1panel/www/ssl"

# 日志文件
LOG_FILE="/var/log/ssl_sync.log"

# 日志函数
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
    echo -e "${GREEN}$(date '+%Y-%m-%d %H:%M:%S') - $1${NC}"
}

error() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: $1" >> "$LOG_FILE"
    echo -e "${RED}$(date '+%Y-%m-%d %H:%M:%S') - ERROR: $1${NC}"
}

warn() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - WARN: $1" >> "$LOG_FILE"
    echo -e "${YELLOW}$(date '+%Y-%m-%d %H:%M:%S') - WARN: $1${NC}"
}

# 检查目录是否存在
check_directories() {
    if [ ! -d "$SOURCE_DIR" ]; then
        error "源目录不存在: $SOURCE_DIR"
        return 1
    fi
    
    # 如果目标目录不存在,则创建
    if [ ! -d "$TARGET_DIR" ]; then
        log "目标目录不存在,正在创建: $TARGET_DIR"
        if ! mkdir -p "$TARGET_DIR"; then
            error "创建目标目录失败: $TARGET_DIR"
            return 1
        fi
        log "目标目录创建成功: $TARGET_DIR"
    fi
    
    log "目录检查通过"
    return 0
}

# 验证证书文件
validate_certificates() {
    log "开始验证证书文件..."
    local valid_count=0
    local error_count=0
    
    # 检查目标目录中的证书文件
    while IFS= read -r -d '' file; do
        filename=$(basename "$file")
        
        if [[ "$filename" == *".crt"* || "$filename" == *".pem"* || "$filename" == *".2crt"* || "$filename" == *".2pem"* ]]; then
            # 简单的证书验证:检查文件是否包含证书标记
            if grep -q "BEGIN CERTIFICATE" "$file" 2>/dev/null; then
                log "证书文件验证通过: $filename"
                ((valid_count++))
            else
                warn "证书文件可能无效(缺少BEGIN CERTIFICATE): $filename"
                ((error_count++))
            fi
        elif [[ "$filename" == *".key"* ]]; then
            # 简单的密钥验证:检查文件是否包含密钥标记
            if grep -q "BEGIN.*PRIVATE KEY" "$file" 2>/dev/null; then
                log "密钥文件验证通过: $filename"
                ((valid_count++))
            else
                warn "密钥文件可能无效(缺少PRIVATE KEY): $filename"
                ((error_count++))
            fi
        fi
    done < <(find "$TARGET_DIR" -type f \( -name "*.crt" -o -name "*.pem" -o -name "*.key" -o -name "*.2crt" -o -name "*.2pem" \) -print0 2>/dev/null)
    
    if [ $error_count -eq 0 ]; then
        log "证书验证完成,所有 $valid_count 个文件验证通过"
    else
        warn "证书验证完成,$valid_count 个文件验证通过,$error_count 个文件可能有问题"
    fi
}

# 同步证书文件到统一目录
sync_certificates() {
    local synced_count=0
    local error_count=0
    
    log "开始同步证书文件到: $TARGET_DIR"

    # 复制所有证书文件到目标目录
    while IFS= read -r -d '' file; do
        filename=$(basename "$file")
        
        # 确定文件类型和权限
        if [[ "$filename" == *".crt"* || "$filename" == *".pem"* || "$filename" == *".2crt"* || "$filename" == *".2pem"* ]]; then
            file_type="证书"
            target_permission="644"
        elif [[ "$filename" == *".key"* ]]; then
            file_type="密钥"
            target_permission="600"
        else
            warn "跳过未知文件类型: $filename"
            continue
        fi
        
        target_file="$TARGET_DIR/$filename"
        
        # 复制文件
        if cp "$file" "$target_file"; then
            # 设置权限
            if chmod "$target_permission" "$target_file"; then
                log "$file_type文件已复制: $filename -> $TARGET_DIR/"
                ((synced_count++))
            else
                error "权限设置失败: $target_file"
                ((error_count++))
            fi
        else
            error "文件复制失败: $filename -> $TARGET_DIR"
            ((error_count++))
        fi
        
    done < <(find "$SOURCE_DIR" -type f \( -name "*.crt" -o -name "*.pem" -o -name "*.key" -o -name "*.2crt" -o -name "*.2pem" \) -print0 2>/dev/null)
    
    if [ $synced_count -eq 0 ]; then
        warn "没有找到任何证书文件进行同步"
    else
        log "同步完成,共处理 $synced_count 个文件,失败 $error_count 个"
    fi
    
    # 如果有错误,返回失败
    if [ $error_count -gt 0 ]; then
        return 1
    fi
    
    return 0
}

# 重新加载Nginx
reload_nginx() {
    log "重新加载Nginx配置..."
    
    # 改进的容器查找逻辑
    nginx_container=$(docker ps --filter "name=1panel-nginx" --format "{{.Names}}" | head -n1)
    
    if [ -z "$nginx_container" ]; then
        # 如果没找到,尝试其他常见的1Panel Nginx容器命名模式
        nginx_container=$(docker ps --filter "name=1panel" --filter "name=nginx" --format "{{.Names}}" | grep -E "(nginx|1panel)" | head -n1)
    fi
    
    if [ -n "$nginx_container" ]; then
        log "找到Nginx容器: $nginx_container"
        if docker exec "$nginx_container" nginx -s reload; then
            log "Nginx配置重新加载成功"
        else
            error "Nginx配置重新加载失败"
            return 1
        fi
    else
        warn "未找到Nginx容器,跳过重新加载"
    fi
}

# 主函数
main() {
    log "开始SSL证书同步..."
    
    # 检查目录
    if ! check_directories; then
        error "目录检查失败,退出脚本"
        exit 1
    fi
    
    # 同步证书
    if ! sync_certificates; then
        error "证书同步过程中出现错误"
        # 不立即退出,继续验证可能复制的文件
    fi
    
    # 验证证书文件
    validate_certificates
    
    # 重新加载Nginx
    reload_nginx
    
    log "SSL证书同步完成"
}

# 执行主函数
main "$@"

Ciallo~(∠・▽< )⌒☆