#!/usr/bin/env bash
# verify-rpo-rto.sh —— 实时 RPO/RTO 状态检查
# 用法：
#   verify-rpo-rto.sh           # 完整检查并打印结果
#   verify-rpo-rto.sh --status-only  # 仅打印摘要（容器启动时调用）
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "${SCRIPT_DIR}/lib.sh"

STATUS_ONLY="${1:-}"

log_info "RPO/RTO 状态检查"

RPO_TARGET_SECONDS=900    # 15 分钟
RTO_TARGET_HOURS=4

PASS=0
WARN=0
FAIL=0

check() {
    local status="$1"
    local msg="$2"
    case "${status}" in
        pass) PASS=$(( PASS + 1 )); log_ok "  ✅ ${msg}" ;;
        warn) WARN=$(( WARN + 1 )); log_warn "  ⚠️  ${msg}" ;;
        fail) FAIL=$(( FAIL + 1 )); log_error "  ❌ ${msg}" ;;
    esac
}

# ──────────────────────────────────────────────────────
# 1. 检查 S3 最新增量备份的时间
# ──────────────────────────────────────────────────────
check_latest_backup_age() {
    local service="$1"
    local s3_prefix="$2"

    local latest
    latest="$(AWS_PROFILE="${AWS_PROFILE}" aws s3 ls \
        "s3://${BACKUP_S3_BUCKET}/${BACKUP_S3_PREFIX}/${s3_prefix}/" \
        --recursive 2>/dev/null \
        | sort | tail -1 | awk '{print $1, $2}' || echo "")"

    if [ -z "${latest}" ]; then
        check fail "${service}: S3 中无备份"
        return
    fi

    local last_date last_time
    last_date=$(echo "${latest}" | awk '{print $1}')
    last_time=$(echo "${latest}" | awk '{print $2}')

    local last_ts
    last_ts="$(date -d "${last_date} ${last_time}" +%s 2>/dev/null \
               || date -j -f '%Y-%m-%d %H:%M:%S' "${last_date} ${last_time}" +%s 2>/dev/null \
               || echo 0)"
    local now
    now=$(date +%s)
    local gap=$(( now - last_ts ))
    local gap_min=$(( gap / 60 ))

    if [ "${gap}" -le "${RPO_TARGET_SECONDS}" ]; then
        check pass "${service}: 最新备份距今 ${gap_min}min (RPO ≤ 15min ✓)"
    elif [ "${gap}" -le $(( RPO_TARGET_SECONDS * 2 )) ]; then
        check warn "${service}: 最新备份距今 ${gap_min}min (接近 RPO 限制)"
    else
        check fail "${service}: 最新备份距今 ${gap_min}min (超出 RPO 15min 限制)"
    fi
}

# ──────────────────────────────────────────────────────
# 2. 检查 S3 最新全量备份时间（应为 < 25 小时）
# ──────────────────────────────────────────────────────
check_full_backup_freshness() {
    local service="$1"
    local s3_prefix="$2"

    local latest
    latest="$(AWS_PROFILE="${AWS_PROFILE}" aws s3 ls \
        "s3://${BACKUP_S3_BUCKET}/${BACKUP_S3_PREFIX}/${s3_prefix}/" \
        2>/dev/null | sort | tail -1 | awk '{print $1, $2}' || echo "")"

    if [ -z "${latest}" ]; then
        check fail "${service} 全量: S3 中无全量备份"
        return
    fi

    local last_date last_time
    last_date=$(echo "${latest}" | awk '{print $1}')
    last_time=$(echo "${latest}" | awk '{print $2}')

    local last_ts
    last_ts="$(date -d "${last_date} ${last_time}" +%s 2>/dev/null \
               || date -j -f '%Y-%m-%d %H:%M:%S' "${last_date} ${last_time}" +%s 2>/dev/null \
               || echo 0)"
    local now
    now=$(date +%s)
    local gap_hours=$(( (now - last_ts) / 3600 ))

    if [ "${gap_hours}" -le 25 ]; then
        check pass "${service} 全量: 最近 ${gap_hours}h 内有全量备份"
    else
        check fail "${service} 全量: 上次全量备份距今 ${gap_hours}h (> 25h)"
    fi
}

# ──────────────────────────────────────────────────────
# 3. 检查 DR 演练报告（最新演练是否在 35 天内）
# ──────────────────────────────────────────────────────
check_dr_drill_freshness() {
    local latest
    latest="$(AWS_PROFILE="${AWS_PROFILE}" aws s3 ls \
        "s3://${BACKUP_S3_BUCKET}/${BACKUP_S3_PREFIX}/dr-reports/" \
        2>/dev/null | sort | tail -1 | awk '{print $1, $2}' || echo "")"

    if [ -z "${latest}" ]; then
        check warn "DR 演练: S3 中无演练报告（首次部署？）"
        return
    fi

    local last_date last_time
    last_date=$(echo "${latest}" | awk '{print $1}')
    last_time=$(echo "${latest}" | awk '{print $2}')

    local last_ts
    last_ts="$(date -d "${last_date} ${last_time}" +%s 2>/dev/null \
               || date -j -f '%Y-%m-%d %H:%M:%S' "${last_date} ${last_time}" +%s 2>/dev/null \
               || echo 0)"
    local now
    now=$(date +%s)
    local gap_days=$(( (now - last_ts) / 86400 ))

    if [ "${gap_days}" -le 35 ]; then
        check pass "DR 演练: 上次演练距今 ${gap_days} 天"
    else
        check warn "DR 演练: 上次演练距今 ${gap_days} 天 (> 35 天，请检查)"
    fi
}

# ──────────────────────────────────────────────────────
# 执行检查
# ──────────────────────────────────────────────────────
check_latest_backup_age "MySQL-增量" "mysql/inc"
check_latest_backup_age "PG-增量" "postgres/inc"
check_full_backup_freshness "MySQL" "mysql/full"
check_full_backup_freshness "PostgreSQL" "postgres/full"
check_dr_drill_freshness

# ──────────────────────────────────────────────────────
# 汇总
# ──────────────────────────────────────────────────────
echo ""
log_info "RPO/RTO 检查汇总"
log_info "  通过: ${PASS}  警告: ${WARN}  失败: ${FAIL}"
log_info "  RPO 目标: ≤ 15min  |  RTO 目标: ≤ ${RTO_TARGET_HOURS}h"

if [ "${FAIL}" -gt 0 ]; then
    log_error "状态: 不达标 ❌"
    exit 1
elif [ "${WARN}" -gt 0 ]; then
    log_warn "状态: 警告 ⚠️"
    exit 0
else
    log_ok "状态: 达标 ✅"
    exit 0
fi
