#!/usr/bin/env python3
"""
Pipeline Health Check — Kiểm tra toàn bộ pipeline trước và sau khi chạy

Usage:
    python3 scripts/healthcheck.py /home/tuan-nguyen/.openclaw/workspace/obsidian
"""

import os
import sys
import json
import hashlib
from datetime import datetime, timezone


def file_hash(filepath: str) -> str:
    """SHA256 của file."""
    h = hashlib.sha256()
    with open(filepath, "rb") as f:
        for chunk in iter(lambda: f.read(8192), b""):
            h.update(chunk)
    return h.hexdigest()[:16]


def check_workspace(base_dir: str) -> dict:
    """Quét workspace, trả về report."""
    report = {
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "base_dir": base_dir,
        "checks": [],
        "files": {},
        "summary": {"pass": 0, "fail": 0, "warn": 0},
    }

    # 1. Kiểm tra các thư mục bắt buộc
    required_dirs = ["extracted", "edited", "edited-notes"]
    for d in required_dirs:
        path = os.path.join(base_dir, d)
        exists = os.path.isdir(path)
        report["checks"].append({
            "item": f"Directory: {d}/",
            "status": "pass" if exists else "warn",
            "message": "OK" if exists else f"Không tồn tại (sẽ tạo tự động khi cần)",
        })
        if not exists:
            report["summary"]["warn"] += 1
        else:
            report["summary"]["pass"] += 1

    # 2. Kiểm tra batch-index.json
    index_path = os.path.join(base_dir, "batch-index.json")
    if os.path.exists(index_path):
        try:
            with open(index_path, "r") as f:
                data = json.load(f)
            total = len(data.get("batches", []))
            done = sum(1 for b in data.get("batches", []) if b.get("status") == "done")
            in_progress = sum(1 for b in data.get("batches", []) if b.get("status") == "in_progress")
            pending = sum(1 for b in data.get("batches", []) if b.get("status") == "pending")
            failed = sum(1 for b in data.get("batches", []) if b.get("status") == "failed")

            report["checks"].append({
                "item": "batch-index.json",
                "status": "pass",
                "message": f"{total} batches: {done} done, {in_progress} in_progress, {pending} pending, {failed} failed",
            })
            report["summary"]["pass"] += 1

            # Cảnh báo nếu có failed batch
            if failed > 0:
                report["checks"].append({
                    "item": "Failed batches",
                    "status": "warn",
                    "message": f"{failed} batch bị failed — cần retry thủ công",
                })
                report["summary"]["warn"] += 1
        except Exception as e:
            report["checks"].append({
                "item": "batch-index.json",
                "status": "fail",
                "message": f"Corrupt: {e}",
            })
            report["summary"]["fail"] += 1
    else:
        report["checks"].append({
            "item": "batch-index.json",
            "status": "warn",
            "message": "Chưa có file index (pipeline chưa khởi tạo)",
        })
        report["summary"]["warn"] += 1

    # 3. Kiểm tra file duplicate (edited file trùng hash với file khác)
    edited_dir = os.path.join(base_dir, "edited")
    if os.path.isdir(edited_dir):
        edited_files = sorted([f for f in os.listdir(edited_dir) if f.endswith(".md")])
        report["files"]["edited_count"] = len(edited_files)

        if len(edited_files) > 1:
            hashes = {}
            for f in edited_files:
                h = file_hash(os.path.join(edited_dir, f))
                if h in hashes:
                    report["checks"].append({
                        "item": f"Duplicate: {f}",
                        "status": "warn",
                        "message": f"Trùng nội dung với {hashes[h]}",
                    })
                    report["summary"]["warn"] += 1
                hashes[h] = f

    # 4. Kiểm tra file size bất thường
    for d in ["extracted", "edited", "edited-notes"]:
        dpath = os.path.join(base_dir, d)
        if os.path.isdir(dpath):
            for f in os.listdir(dpath):
                if f.endswith(".md"):
                    fpath = os.path.join(dpath, f)
                    size = os.path.getsize(fpath)
                    if size < 100:  # file quá nhỏ
                        report["checks"].append({
                            "item": f"Small file: {d}/{f}",
                            "status": "warn",
                            "message": f"Chỉ {size} bytes — có thể rỗng hoặc lỗi",
                        })
                        report["summary"]["warn"] += 1

    return report


def main():
    base_dir = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()

    print("=" * 60)
    print("🏗️  PIPELINE HEALTH CHECK")
    print("=" * 60)

    report = check_workspace(base_dir)

    for check in report["checks"]:
        icon = {"pass": "✅", "warn": "⚠️", "fail": "❌"}[check["status"]]
        print(f"  {icon} {check['item']}: {check['message']}")

    print("-" * 60)
    s = report["summary"]
    print(f"  ✅ {s['pass']} pass  ⚠️ {s['warn']} warn  ❌ {s['fail']} fail")

    if s["fail"] > 0:
        print("\n❌ HEALTH CHECK FAILED — fix lỗi trước khi chạy pipeline")
        sys.exit(1)

    print("\n✅ HEALTH CHECK PASSED")
    sys.exit(0)


if __name__ == "__main__":
    main()
