"""重跑 4 个失败任务（v3），捕获完整错误输出"""
import os, sys, subprocess, time
from pathlib import Path
from datetime import datetime
from dotenv import load_dotenv
from zoneinfo import ZoneInfo

load_dotenv(Path(__file__).resolve().parents[2] / ".env")

TZ = ZoneInfo("Asia/Shanghai")
ETL_CWD = Path(__file__).resolve().parents[2] / "apps" / "etl" / "connectors" / "feiqiu"

TASKS = [
    "DWS_FINANCE_INCOME_STRUCTURE",
    "DWS_ASSISTANT_MONTHLY",
    "DWS_RELATION_INDEX",
    "DWS_SPENDING_POWER_INDEX",
]

COMMON_ARGS = [
    "--window-start", "2025-11-01 00:00:00",
    "--window-end", "2026-02-27 00:00:00",
    "--window-split-days", "30",
    "--force-full",
]


def run_task(task: str) -> dict:
    layer = "INDEX" if task.endswith("_INDEX") else "DWS"
    cmd = [
        "uv", "run", "--package", "etl-feiqiu",
        "python", "-m", "cli.main",
        "--layers", layer,
        "--tasks", task,
        *COMMON_ARGS,
    ]
    start = time.time()
    proc = subprocess.run(
        cmd, cwd=str(ETL_CWD),
        capture_output=True, text=True,
        encoding="utf-8", errors="replace",
        timeout=300,
    )
    elapsed = time.time() - start
    output = proc.stdout + proc.stderr

    has_error = any(
        kw in line for line in output.splitlines()
        for kw in ("ERROR", "CRITICAL", "Traceback")
    )
    return {
        "task": task, "exit_code": proc.returncode,
        "elapsed": elapsed, "success": proc.returncode == 0 and not has_error,
        "output": output,
    }


def main():
    now = datetime.now(TZ)
    print(f"{'='*60}")
    print(f"失败任务重跑 v3 | {now.isoformat()}")
    print(f"{'='*60}\n")

    results = []
    for i, task in enumerate(TASKS, 1):
        print(f"[{i}/{len(TASKS)}] {task} ...", end=" ", flush=True)
        try:
            r = run_task(task)
            results.append(r)
            icon = "OK" if r["success"] else "FAIL"
            print(f"{icon} ({r['elapsed']:.0f}s)")
            if not r["success"]:
                # 打印最后 30 行
                lines = r["output"].splitlines()
                for line in lines[-30:]:
                    print(f"  | {line}")
        except subprocess.TimeoutExpired:
            results.append({"task": task, "success": False, "elapsed": 300,
                            "exit_code": -1, "output": "TIMEOUT"})
            print("TIMEOUT")

    ok = [r for r in results if r["success"]]
    fail = [r for r in results if not r["success"]]
    print(f"\n{'='*60}")
    print(f"结果: {len(ok)}/{len(results)} 成功")

    # 保存日志
    log_root = os.environ.get("SYSTEM_LOG_ROOT")
    if not log_root:
        raise RuntimeError("SYSTEM_LOG_ROOT 未设置")
    log_dir = Path(log_root)
    log_dir.mkdir(parents=True, exist_ok=True)
    log_file = log_dir / f"{now.strftime('%Y%m%d')}_rerun_v3.log"
    with open(log_file, "w", encoding="utf-8") as f:
        for r in results:
            icon = "OK" if r["success"] else "FAIL"
            f.write(f"[{icon}] {r['task']} ({r['elapsed']:.0f}s)\n")
            f.write(f"{r['output']}\n{'='*60}\n")
    print(f"日志: {log_file}")
    sys.exit(0 if not fail else 1)


if __name__ == "__main__":
    main()
