#!/bin/bash

# 考陪练系统数据库自动备份脚本
# 作者: AI Assistant
# 日期: 2025-09-23

set -e  # 遇到错误立即退出

# 配置变量
BACKUP_DIR="/root/aiedu/kaopeilian-backend/backups"
CONTAINER_NAME="kaopeilian_mysql"
DB_NAME="kaopeilian"
DB_USER="root"
DB_PASSWORD="Kaopeilian2025!@#"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/kaopeilian_backup_${DATE}.sql"
LOG_FILE="${BACKUP_DIR}/backup.log"
RETENTION_DAYS=30  # 保留30天的备份

# 创建备份目录
mkdir -p "${BACKUP_DIR}"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "${LOG_FILE}"
}

# 检查Docker容器是否运行
check_container() {
    if ! docker ps | grep -q "${CONTAINER_NAME}"; then
        log "ERROR: MySQL容器 ${CONTAINER_NAME} 未运行"
        exit 1
    fi
}

# 执行数据库备份
backup_database() {
    log "开始备份Docker容器中的数据库 ${DB_NAME}..."
    
    # 检查容器是否运行
    if ! docker ps | grep -q "${CONTAINER_NAME}"; then
        log "ERROR: MySQL容器 ${CONTAINER_NAME} 未运行"
        return 1
    fi
    
    # 使用docker exec执行mysqldump，将输出重定向到宿主机文件
    if docker exec "${CONTAINER_NAME}" mysqldump \
        -u"${DB_USER}" \
        -p"${DB_PASSWORD}" \
        --single-transaction \
        --routines \
        --triggers \
        --events \
        --hex-blob \
        --default-character-set=utf8mb4 \
        --lock-tables=false \
        --add-drop-database \
        --create-options \
        "${DB_NAME}" > "${BACKUP_FILE}" 2>/dev/null; then
        
        # 检查备份文件大小
        if [ -f "${BACKUP_FILE}" ] && [ -s "${BACKUP_FILE}" ]; then
            BACKUP_SIZE=$(du -h "${BACKUP_FILE}" | cut -f1)
            log "备份完成: ${BACKUP_FILE} (大小: ${BACKUP_SIZE})"
            
            # 验证备份文件内容（检查是否包含CREATE DATABASE语句）
            if grep -q "CREATE DATABASE" "${BACKUP_FILE}"; then
                log "备份文件验证成功"
                return 0
            else
                log "WARNING: 备份文件可能不完整"
                return 0  # 仍然算作成功，但记录警告
            fi
        else
            log "ERROR: 备份文件为空或不存在"
            rm -f "${BACKUP_FILE}"
            return 1
        fi
    else
        log "ERROR: 数据库备份失败"
        return 1
    fi
}

# 压缩备份文件
compress_backup() {
    if [ -f "${BACKUP_FILE}" ]; then
        log "压缩备份文件..."
        gzip "${BACKUP_FILE}"
        COMPRESSED_FILE="${BACKUP_FILE}.gz"
        COMPRESSED_SIZE=$(du -h "${COMPRESSED_FILE}" | cut -f1)
        log "压缩完成: ${COMPRESSED_FILE} (大小: ${COMPRESSED_SIZE})"
    fi
}

# 清理过期备份
cleanup_old_backups() {
    log "清理 ${RETENTION_DAYS} 天前的备份文件..."
    find "${BACKUP_DIR}" -name "kaopeilian_backup_*.sql.gz" -mtime +${RETENTION_DAYS} -delete
    find "${BACKUP_DIR}" -name "kaopeilian_backup_*.sql" -mtime +${RETENTION_DAYS} -delete
    log "过期备份清理完成"
}

# 发送备份状态通知（可选）
send_notification() {
    local status=$1
    local message=$2
    
    # 这里可以集成邮件、钉钉、微信等通知方式
    log "通知: ${status} - ${message}"
    
    # 示例：写入状态文件供监控系统读取
    echo "{\"timestamp\":\"$(date -Iseconds)\",\"status\":\"${status}\",\"message\":\"${message}\"}" > "${BACKUP_DIR}/backup_status.json"
}

# 主函数
main() {
    log "========== 数据库备份开始 =========="
    
    # 检查容器状态
    check_container
    
    # 执行备份
    if backup_database; then
        # 压缩备份
        compress_backup
        
        # 清理过期备份
        cleanup_old_backups
        
        # 发送成功通知
        send_notification "SUCCESS" "数据库备份成功完成"
        log "========== 数据库备份完成 =========="
        exit 0
    else
        # 发送失败通知
        send_notification "FAILED" "数据库备份失败"
        log "========== 数据库备份失败 =========="
        exit 1
    fi
}

# 执行主函数
main "$@"
