import pathlib, os, sys, json, traceback

# =============================================================================
# 部署启动自检脚本 v1.0
# 在 GoldAutoTradeEngine.exe 启动时调用，检查所有关键通路
# 任何错误都给出清晰的修复指引，而不是崩溃堆栈
# =============================================================================

def check(path: str, name: str, fix: str = "") -> bool:
    """Run a check and print result. Returns True if passed."""
    print(f"  [{name}]...", end=" ")
    try:
        ok = check_func[path]()
        if ok:
            print("OK")
        else:
            print("FAIL")
            if fix:
                print(f"    → {fix}")
        return ok
    except Exception as e:
        print(f"FAIL ({e})")
        if fix:
            print(f"    → {fix}")
        return False

def check1_data_dir():
    """Check: AppData/GoldAutoTrade directory exists and is writable"""
    appdata = pathlib.Path(os.environ.get("APPDATA", "")) / "GoldAutoTrade"
    appdata.mkdir(parents=True, exist_ok=True)
    test_file = appdata / ".write_test"
    test_file.write_text("ok")
    test_file.unlink()
    return True

def check2_mt5_bridge():
    """Check: MT5 bridge files directory exists"""
    mt5_dir = os.environ.get("EA_BRIDGE_FILES_DIR", "")
    if mt5_dir:
        p = pathlib.Path(mt5_dir).expanduser()
        if p.exists():
            return True
    
    # Auto-detect common MT5 paths
    candidates = [
        pathlib.Path.home() / "AppData/Roaming/MetaQuotes/Terminal/Common/Files",
        pathlib.Path("C:/Program Files/MetaTrader 5/MQL5/Files"),
    ]
    
    # Also check for Wine paths
    wine_prefixes = [
        pathlib.Path.home() / "Library/Application Support/net.metaquotes.wine.metatrader5",
        pathlib.Path.home() / ".wine",
    ]
    for wp in wine_prefixes:
        for cand in wp.glob("**/MetaQuotes/Terminal/*/Common/Files"):
            candidates.append(cand)
    
    for cand in candidates:
        if cand.exists():
            bridge = cand / "gold_autotrade" / "bridge"
            if bridge.exists():
                return True
    
    return False

def check3_symbol_discovery():
    """Check: can detect gold symbol from MT5"""
    # Try to find market_snapshot.json and extract symbol
    appdata = pathlib.Path(os.environ.get("APPDATA", "")) / "GoldAutoTrade"
    
    # Check multiple locations
    snapshot_paths = [
        appdata / "data" / "bridge" / "market_snapshot.json",
        appdata.parent / "bridge" / "market_snapshot.json",
    ]
    
    # Also check EA bridge paths
    mt5_base = _find_mt5_files_dir()
    if mt5_base:
        snapshot_paths.append(mt5_base / "gold_autotrade" / "bridge" / "market_snapshot.json")
    
    for sp in snapshot_paths:
        if sp.exists():
            try:
                data = json.loads(sp.read_text(encoding="utf-8"))
                symbol = data.get("symbol", "")
                if not symbol:
                    # Try instruments
                    instruments = data.get("instruments", {})
                    for key in instruments:
                        if "XAU" in key.upper() or "GOLD" in key.upper():
                            symbol = key
                            break
                if symbol:
                    return True
            except:
                continue
    
    # 首次安装 / EA 未运行 → 不阻塞启动, pipeline 会自行检测
    return True

def check4_network_access():
    """Check: can reach key services.
    首次安装时 API key 可能未配置, 不阻塞启动。
    """
    # 先检查是否有 API key 配置
    try:
        llm_dir = pathlib.Path(os.environ.get("APPDATA", "")) / "GoldAutoTrade" / "llm_config"
        openclaw = llm_dir / "openclaw.json"
        home_openclaw = pathlib.Path.home() / ".openclaw" / "openclaw.json"
        has_key = False
        for cfg_path in (openclaw, home_openclaw):
            if cfg_path.exists():
                cfg = json.loads(cfg_path.read_text(encoding="utf-8"))
                providers = cfg.get("models", {}).get("providers", {})
                for info in providers.values():
                    if info.get("apiKey", ""):
                        has_key = True
                        break
        if not has_key:
            # 无 API key → 这不是故障, 只是未配置
            return True
    except:
        pass

    import urllib.request
    try:
        req = urllib.request.Request("https://api.deepseek.com/v1/models", headers={"User-Agent": "GAT-Diag"})
        urllib.request.urlopen(req, timeout=5)
        return True
    except:
        pass
    # 有 key 但连不上 → 网络问题, 但也不阻塞
    return True

def check5_license():
    """Check: license file exists and is valid"""
    try:
        from src.license.validator import load_license
        lic = load_license(auto_trial=False)
        return lic is not None and not lic.get("error")
    except:
        return False

def check6_execution_state():
    """Check: execution state file is writable"""
    appdata = pathlib.Path(os.environ.get("APPDATA", "")) / "GoldAutoTrade"
    state_path = appdata / "data" / "execution_state.json"
    state_path.parent.mkdir(parents=True, exist_ok=True)
    if not state_path.exists():
        state_path.write_text('{"signals":{}}')
    return True

def check7_config_files():
    """Check: config files exist and are valid JSON"""
    appdata = pathlib.Path(os.environ.get("APPDATA", "")) / "GoldAutoTrade"
    configs = [
        appdata / "config" / "risk_governor_rules.json",
        appdata / "config" / "strategy_rules_v3.json",
    ]
    for cfg in configs:
        if not cfg.exists():
            return False
        try:
            json.loads(cfg.read_text(encoding="utf-8"))
        except:
            return False
    return True

def check8_python_env():
    """Check: Python environment is functional"""
    try:
        import sqlite3, threading, json, pathlib, os, time, datetime
        return True
    except:
        return False

def _find_mt5_files_dir():
    for candidate in [
        pathlib.Path.home() / "AppData/Roaming/MetaQuotes/Terminal/Common/Files",
        pathlib.Path("C:/Program Files/MetaTrader 5/MQL5/Files"),
    ]:
        if candidate.exists():
            return candidate
    return None

check_func = {
    "data_dir": check1_data_dir,
    "mt5_bridge": check2_mt5_bridge,
    "symbol": check3_symbol_discovery,
    "network": check4_network_access,
    "license": check5_license,
    "state": check6_execution_state,
    "config": check7_config_files,
    "python": check8_python_env,
}

FIX_GUIDE = {
    "data_dir": "数据目录无法创建。请以管理员身份运行一次。",
    "mt5_bridge": "首次安装需在 设置→MT5路径 中配置 MT5 终端路径。系统将自动创建桥接目录并部署 EA 文件。",
    "symbol": "桥接数据尚未产生。请确认 MT5 已运行且 Bridge EA 已加载到 XAUUSD 图表。首次使用属正常现象。",
    "network": "AI API Key 未配置或网络受限。请在 设置→大模型配置 中添加 API Key。纯技术分析模式仍可正常交易。",
    "license": "授权无效或已过期。试用授权需首次运行时连接到服务器激活。",
    "state": "执行状态文件无法写入。请检查磁盘权限。",
    "config": "配置文件缺失或损坏。请重新从安装包复制 config/ 目录。",
    "python": "Python 环境异常。请确认已安装 Python 3.9+。",
}

if __name__ == "__main__":
    import argparse
    ap = argparse.ArgumentParser()
    ap.add_argument("--check", choices=list(check_func.keys()), help="Run a specific check")
    args = ap.parse_args()
    
    if args.check:
        ok = check(args.check, args.check, FIX_GUIDE.get(args.check, ""))
        sys.exit(0 if ok else 1)
    
    print("=" * 60)
    print("Gold AutoTrade - System Health Check")
    print("=" * 60)
    print(f"OS: {sys.platform}")
    print(f"Python: {sys.version}")
    print(f"AppData: {os.environ.get('APPDATA', 'N/A')}")
    print()
    
    passed = 0
    failed = 0
    for name, _ in check_func.items():
        ok = check(name, name, FIX_GUIDE.get(name, ""))
        if ok:
            passed += 1
        else:
            failed += 1
    
    print()
    print(f"Result: {passed} passed, {failed} failed")
    if failed > 0:
        print()
        print("TROUBLESHOOTING:")
        print("  1. 确保以管理员身份运行")
        print("  2. 确保 MT5 已打开且 Bridge EA 在图表上")
        print("  3. 检查防火墙和网络连接")
        print("  4. 检查 DeepSeek API Key 是否已配置")
    sys.exit(0 if failed == 0 else 1)
