#!/bin/bash
#
# Copyright(c) 2024-2026 China Telecom Cloud Technologies Co., Ltd. All rights
# reserved. ctscat is licensed under Mulan PSL v2. You can use this software
# according to the terms and conditions of the Mulan PSL V2. You may obtain a
# copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2.
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.  See the Mulan PSL v2 for
# more details.
#

# TRACK-SYSTEM 测试覆盖率自动化脚本
# 用途: 运行 Tarpaulin 生成覆盖率报告,解析结果并记录到 checklist

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

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 默认参数
COVERAGE_THRESHOLD=${1:-50}  # 默认阈值 50%
TIMEOUT=240                   # 默认超时 240 秒
OUTPUT_FORMAT="Html"          # 默认输出格式
REPORT_FILE="tarpaulin-report.html"
CHECKLIST_FILE="docs/coverage/checklist.md"

# 打印带颜色的信息
print_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

print_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

print_error() {
    echo -e "${RED}❌ $1${NC}"
}

print_header() {
    echo ""
    echo -e "${BLUE}================================================${NC}"
    echo -e "${BLUE}$1${NC}"
    echo -e "${BLUE}================================================${NC}"
    echo ""
}

# 帮助信息
show_help() {
    echo "用法: $0 [覆盖率阈值]"
    echo ""
    echo "参数:"
    echo "  覆盖率阈值    期望的最低覆盖率百分比 (默认: 50)"
    echo ""
    echo "示例:"
    echo "  $0          # 使用默认阈值 50%"
    echo "  $0 80       # 要求覆盖率 >= 80%"
    echo "  $0 90       # 要求覆盖率 >= 90%"
    echo ""
    echo "环境变量:"
    echo "  TIMEOUT               Tarpaulin 超时时间 (秒, 默认: 240)"
    echo "  OUTPUT_FORMAT         输出格式 (默认: Html)"
    echo "  SKIP_THRESHOLD_CHECK  跳过阈值检查 (设置为 1)"
    exit 0
}

# 检查参数
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
    show_help
fi

# 验证阈值参数
if ! [[ "$COVERAGE_THRESHOLD" =~ ^[0-9]+$ ]] || [ "$COVERAGE_THRESHOLD" -lt 0 ] || [ "$COVERAGE_THRESHOLD" -gt 100 ]; then
    print_error "无效的覆盖率阈值: $COVERAGE_THRESHOLD"
    echo "阈值必须是 0-100 之间的整数"
    exit 1
fi

print_header "TRACK-SYSTEM 测试覆盖率检查"

print_info "覆盖率阈值: ${COVERAGE_THRESHOLD}%"
print_info "超时时间: ${TIMEOUT} 秒"
print_info "输出格式: ${OUTPUT_FORMAT}"
echo ""

# 1. 检查 Tarpaulin 是否已安装
print_info "检查 cargo-tarpaulin 是否已安装..."
if ! command -v cargo-tarpaulin &> /dev/null; then
    print_warning "cargo-tarpaulin 未安装,正在安装..."
    cargo install cargo-tarpaulin || {
        print_error "cargo-tarpaulin 安装失败"
        echo ""
        echo "请手动安装: cargo install cargo-tarpaulin"
        exit 1
    }
    print_success "cargo-tarpaulin 安装成功"
else
    TARPAULIN_VERSION=$(cargo tarpaulin --version | head -1)
    print_success "已安装: $TARPAULIN_VERSION"
fi
echo ""

# 2. 清理旧的报告文件
print_info "清理旧的报告文件..."
if [ -f "$REPORT_FILE" ]; then
    rm -f "$REPORT_FILE"
    print_success "已删除旧报告: $REPORT_FILE"
fi
echo ""

# 3. 运行 Tarpaulin
print_header "运行 Tarpaulin 测试覆盖率分析"
print_info "这可能需要几分钟时间,请耐心等待..."
echo ""

START_TIME=$(date +%s)

# 运行 Tarpaulin 并捕获输出
TARPAULIN_OUTPUT=$(cargo tarpaulin \
    --workspace \
    --timeout $TIMEOUT \
    --out $OUTPUT_FORMAT \
    --engine llvm \
    --verbose \
    --exclude-files "migration/*"
    2>&1) || {
    TARPAULIN_EXIT_CODE=$?
    print_error "Tarpaulin 运行失败 (退出码: $TARPAULIN_EXIT_CODE)"
    echo ""
    echo "错误输出:"
    echo "$TARPAULIN_OUTPUT" | tail -20
    exit $TARPAULIN_EXIT_CODE
}

END_TIME=$(date +%s)
ELAPSED_TIME=$((END_TIME - START_TIME))

echo "$TARPAULIN_OUTPUT"
echo ""

print_success "Tarpaulin 运行完成 (耗时: ${ELAPSED_TIME}s)"
echo ""

# 4. 解析覆盖率结果
print_info "解析覆盖率结果..."

# 从输出中提取覆盖率百分比 (格式: XX.XX% coverage, XXXX/XXXX lines covered)
COVERAGE_LINE=$(echo "$TARPAULIN_OUTPUT" | grep -E "[0-9]+\.[0-9]+% coverage" | tail -1)

if [ -z "$COVERAGE_LINE" ]; then
    print_error "无法从 Tarpaulin 输出中解析覆盖率"
    echo ""
    echo "Tarpaulin 输出末尾:"
    echo "$TARPAULIN_OUTPUT" | tail -10
    exit 1
fi

# 提取覆盖率百分比 (例如: 30.19)
COVERAGE_PERCENT=$(echo "$COVERAGE_LINE" | grep -oE "[0-9]+\.[0-9]+" | head -1)

# 提取覆盖行数 (例如: 7052/23358)
COVERAGE_LINES=$(echo "$COVERAGE_LINE" | grep -oE "[0-9]+/[0-9]+ lines" | sed 's/ lines//')

print_success "当前覆盖率: ${COVERAGE_PERCENT}% ($COVERAGE_LINES 行)"
echo ""

# 5. 检查报告文件是否生成
print_info "检查报告文件..."
if [ -f "$REPORT_FILE" ]; then
    REPORT_SIZE=$(ls -lh "$REPORT_FILE" | awk '{print $5}')
    print_success "报告已生成: $REPORT_FILE (大小: $REPORT_SIZE)"
    print_info "在浏览器中打开: file://$(pwd)/$REPORT_FILE"
else
    print_warning "HTML 报告文件未找到: $REPORT_FILE"
fi
echo ""

# 6. 记录到 checklist.md
print_info "更新覆盖率检查清单..."

# 检查 checklist 文件是否存在
if [ ! -f "$CHECKLIST_FILE" ]; then
    print_error "检查清单文件不存在: $CHECKLIST_FILE"
    echo "请先创建文档框架 (任务 1)"
    exit 1
fi

# 生成记录内容
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
RUNNER="${USER:-CI}"

# 判断阶段
PHASE="Phase1"
if (( $(echo "$COVERAGE_PERCENT >= 80" | bc -l) )); then
    PHASE="Phase3"
elif (( $(echo "$COVERAGE_PERCENT >= 50" | bc -l) )); then
    PHASE="Phase2"
fi

# 判断是否达标
PASS_EMOJI="❌"
PASS_TEXT="未达标 (目标 ≥${COVERAGE_THRESHOLD}%)"
if (( $(echo "$COVERAGE_PERCENT >= $COVERAGE_THRESHOLD" | bc -l) )); then
    PASS_EMOJI="✅"
    PASS_TEXT="达标"
fi

# 追加记录到 checklist
cat >> "$CHECKLIST_FILE" << EOF

---
**日期**: $TIMESTAMP
**覆盖率**: ${COVERAGE_PERCENT}% ($COVERAGE_LINES 行)
**阶段**: $PHASE
**是否达标**: $PASS_EMOJI ($PASS_TEXT)
**运行者**: $RUNNER
**运行时间**: ${ELAPSED_TIME}s
**备注**: 自动化脚本运行

EOF

print_success "覆盖率记录已追加到 $CHECKLIST_FILE"
echo ""

# 7. 覆盖率阈值检查
if [ "${SKIP_THRESHOLD_CHECK:-0}" != "1" ]; then
    print_header "覆盖率阈值检查"

    print_info "期望阈值: ≥${COVERAGE_THRESHOLD}%"
    print_info "实际覆盖率: ${COVERAGE_PERCENT}%"
    echo ""

    if (( $(echo "$COVERAGE_PERCENT >= $COVERAGE_THRESHOLD" | bc -l) )); then
        print_success "覆盖率达标! 🎉"
        echo ""
        echo "当前覆盖率 ${COVERAGE_PERCENT}% 已达到或超过阈值 ${COVERAGE_THRESHOLD}%"
        EXIT_CODE=0
    else
        print_error "覆盖率未达标! ⚠️"
        echo ""
        echo "当前覆盖率 ${COVERAGE_PERCENT}% 低于阈值 ${COVERAGE_THRESHOLD}%"
        echo ""
        COVERAGE_GAP=$(echo "$COVERAGE_THRESHOLD - $COVERAGE_PERCENT" | bc)
        print_warning "还需提升 ${COVERAGE_GAP}% 的覆盖率"
        echo ""
        echo "建议:"
        echo "  1. 打开报告文件查看未覆盖的代码: $REPORT_FILE"
        echo "  2. 优先为 0% 覆盖率的文件添加测试"
        echo "  3. 参考测试指南: docs/coverage/guide.md"
        EXIT_CODE=1
    fi
else
    print_info "跳过阈值检查 (SKIP_THRESHOLD_CHECK=1)"
    EXIT_CODE=0
fi

echo ""
print_header "测试覆盖率检查完成"

# 打印摘要
echo "📊 覆盖率摘要:"
echo "   覆盖率: ${COVERAGE_PERCENT}%"
echo "   覆盖行数: $COVERAGE_LINES"
echo "   阈值: ≥${COVERAGE_THRESHOLD}%"
echo "   运行时间: ${ELAPSED_TIME}s"
echo "   报告文件: $REPORT_FILE"
echo ""

exit $EXIT_CODE