#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
调查 ETL 在 2026-02-14 后停止处理的原因

用法：
    cd C:/NeoZQYY
    python scripts/ops/_investigate_etl_gap.py
"""

import os
import sys
from datetime import datetime
from pathlib import Path
import glob

# 添加项目根目录到 Python 路径
project_root = Path(__file__).parent.parent.parent
sys.path.insert(0, str(project_root))

# 加载环境变量
from dotenv import load_dotenv
load_dotenv(project_root / ".env")

def main():
    """调查 ETL 处理中断的原因"""
    
    log_dir = Path(os.environ["SYSTEM_LOG_ROOT"])
    
    print("🔍 调查 ETL 在 2026-02-14 后停止处理的原因")
    print("=" * 60)
    
    # 1. 检查 ETL 日志目录
    etl_log_root = os.environ.get("LOG_ROOT")
    if etl_log_root:
        etl_log_dir = Path(etl_log_root)
        print(f"📂 ETL 日志目录: {etl_log_dir}")
        
        if etl_log_dir.exists():
            # 查找最近的日志文件
            log_files = list(etl_log_dir.glob("*.log"))
            if log_files:
                # 按修改时间排序
                log_files.sort(key=lambda f: f.stat().st_mtime, reverse=True)
                print(f"📋 找到 {len(log_files)} 个日志文件")
                
                # 检查最近 5 个日志文件
                for i, log_file in enumerate(log_files[:5]):
                    mtime = datetime.fromtimestamp(log_file.stat().st_mtime)
                    size = log_file.stat().st_size
                    print(f"  {i+1}. {log_file.name} - {mtime.strftime('%Y-%m-%d %H:%M:%S')} ({size} bytes)")
                
                # 读取最新日志的尾部
                latest_log = log_files[0]
                print(f"\\n📄 最新日志文件内容 ({latest_log.name}):")
                try:
                    with open(latest_log, 'r', encoding='utf-8') as f:
                        lines = f.readlines()
                        # 显示最后 20 行
                        tail_lines = lines[-20:] if len(lines) > 20 else lines
                        for line in tail_lines:
                            print(f"    {line.rstrip()}")
                except Exception as e:
                    print(f"    ❌ 读取日志失败: {e}")
            else:
                print("❌ 未找到 ETL 日志文件")
        else:
            print(f"❌ ETL 日志目录不存在: {etl_log_dir}")
    
    # 2. 数据库发现总结
    print(f"\\n📊 数据库调查结果:")
    print(f"  - ODS 层: 有 2026-02-15 后的数据 (89 条 2026-02-24/25 的记录)")
    print(f"  - DWD 层: 没有 2026-02-15 后的数据 (最晚到 2026-02-14 00:21:21)")
    print(f"  - 缺失数据: 2026-02-24 (80条) + 2026-02-25 (9条) = 89 条记录")
    
    # 3. 可能的原因分析
    print(f"\\n🔍 可能的原因:")
    print(f"  1. ETL DWD 任务在 2026-02-14 后没有运行")
    print(f"  2. DWD 任务运行了但处理失败 (错误/异常)")
    print(f"  3. DWD 任务的时间窗口配置问题")
    print(f"  4. 数据质量检查导致数据被过滤")
    print(f"  5. 春节期间手动停止了 ETL 调度")
    
    # 4. 建议的解决步骤
    print(f"\\n🔧 建议解决步骤:")
    print(f"  1. 检查 ETL 调度状态 (cron/systemd/手动)")
    print(f"  2. 手动运行 DWD_LOAD_FROM_ODS 任务处理缺失数据")
    print(f"  3. 检查 ETL 配置中的时间窗口设置")
    print(f"  4. 验证数据质量规则是否过于严格")
    
    # 5. 生成调查报告
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    report_file = log_dir / f"etl_gap_investigation_{timestamp}.md"
    
    with open(report_file, "w", encoding="utf-8") as f:
        f.write("# ETL 数据处理中断调查报告\\n\\n")
        f.write(f"**调查时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\\n\\n")
        
        f.write("## 🎯 问题描述\\n\\n")
        f.write("ETL 流程在 2026-02-14 后停止将 ODS 数据处理到 DWD 层，导致 SPI 任务基于不完整数据产生警告。\\n\\n")
        
        f.write("## 📊 数据差异分析\\n\\n")
        f.write("| 层级 | 最晚数据时间 | 2026-02-15后记录数 |\\n")
        f.write("|------|-------------|------------------|\\n")
        f.write("| ODS | 2026-02-25 03:14:45 | 89 条 |\\n")
        f.write("| DWD | 2026-02-14 00:21:21 | 0 条 |\\n\\n")
        
        f.write("### 缺失数据明细\\n")
        f.write("- **2026-02-24**: 80 条记录未处理\\n")
        f.write("- **2026-02-25**: 9 条记录未处理\\n\\n")
        
        f.write("## 🔍 可能原因\\n\\n")
        f.write("1. **ETL 调度中断**: 春节期间可能手动停止了 ETL 调度\\n")
        f.write("2. **任务执行失败**: DWD 任务遇到错误但未被发现\\n")
        f.write("3. **配置问题**: 时间窗口或数据过滤规则问题\\n")
        f.write("4. **资源问题**: 数据库连接、磁盘空间等资源限制\\n\\n")
        
        f.write("## 🔧 解决方案\\n\\n")
        f.write("### 立即措施\\n")
        f.write("```bash\\n")
        f.write("# 手动运行 DWD 任务处理缺失数据\\n")
        f.write("cd apps/etl/connectors/feiqiu\\n")
        f.write("python -m cli.main --tasks DWD_LOAD_FROM_ODS\\n")
        f.write("```\\n\\n")
        
        f.write("### 验证措施\\n")
        f.write("1. 检查 DWD 层是否有新数据\\n")
        f.write("2. 重新运行 SPI 任务验证警告是否消失\\n")
        f.write("3. 建立 ETL 数据延迟监控\\n\\n")
        
        f.write("## 📋 后续预防\\n\\n")
        f.write("1. **监控告警**: 建立 DWD 数据延迟监控\\n")
        f.write("2. **自动恢复**: 配置 ETL 任务自动重试机制\\n")
        f.write("3. **日志审计**: 定期检查 ETL 运行日志\\n")
        f.write("4. **业务日历**: 集成业务日历避免误判\\n")
    
    print(f"\\n📋 调查报告已生成: {report_file}")
    
    # 6. 提供手动修复命令
    print(f"\\n🚀 立即修复命令:")
    print(f"cd apps/etl/connectors/feiqiu")
    print(f"python -m cli.main --tasks DWD_LOAD_FROM_ODS")


if __name__ == "__main__":
    main()