#!/usr/bin/env python3
"""data_freshness.py — 数据新鲜度校验

所有报告管道在生成输出前必须调用 check_fresh()。
返回 (pass: bool, details: str)，如果数据过期则阻止生成操作建议。

用法：
    from data_freshness import check_fresh
    ok, msg = check_fresh()
    if not ok:
        print(f"⚠️ 数据过期: {msg}")
        sys.exit(0)  # 不生成报告

校验规则：
- 盘中 (9:30~15:00)：price/live_prices.json 必须在 5 分钟内刷新
- 盘后 (9:30以前/15:00以后)：允许最长 120 分钟
- 周末/节假日：跳过校验
"""

import json, os
from datetime import datetime, timedelta

LIVE_PRICES_PATH = "/home/hmo/web-dashboard/data/live_prices.json"
PORTFOLIO_PATH = "/home/hmo/web-dashboard/data/portfolio.json"


def is_market_hours():
    now = datetime.now()
    if now.weekday() >= 5:  # 周六日
        return False, "weekend"
    t = now.hour * 60 + now.minute
    if 9*60+30 <= t <= 15*60:
        return True, "trading"
    return False, "closed"


def check_fresh():
    """返回 (ok: bool, msg: str)"""
    now = datetime.now()
    
    # 先看是不是交易日
    in_market, period = is_market_hours()
    
    max_age_min = 5 if in_market else 120
    
    # 主指标：live_prices.json
    if os.path.exists(LIVE_PRICES_PATH):
        try:
            lp = json.load(open(LIVE_PRICES_PATH))
            lp_time = lp.get("updated_at", "")
            if not lp_time:
                return False, "live_prices.json updated_at 为空"
            lp_dt = datetime.fromisoformat(lp_time)
            age = (now - lp_dt).total_seconds() / 60
            if age > max_age_min:
                return False, f"live_prices.json 已 {age:.0f} 分钟未更新（阈值 {max_age_min} 分钟）"
            return True, f"数据新鲜（{age:.0f} 分钟前）"
        except Exception as e:
            return False, f"live_prices.json 读取失败: {e}"
    else:
        # fallback: portfolio.json
        if os.path.exists(PORTFOLIO_PATH):
            try:
                pf = json.load(open(PORTFOLIO_PATH))
                pf_time = pf.get("updated_at", "")
                if not pf_time:
                    return False, "portfolio.json updated_at 为空"
                pf_dt = datetime.fromisoformat(pf_time)
                age = (now - pf_dt).total_seconds() / 60
                if age > max_age_min:
                    return False, f"portfolio.json 已 {age:.0f} 分钟未更新（阈值 {max_age_min} 分钟）"
                return True, f"数据新鲜（portfolio.json {age:.0f} 分钟前）"
            except Exception as e:
                return False, f"portfolio.json 读取失败: {e}"
        return False, "live_prices.json 和 portfolio.json 均不存在"


if __name__ == "__main__":
    ok, msg = check_fresh()
    print(f"{'✅' if ok else '❌'} {msg}")
