# -*- coding: utf-8 -*-
"""fix-split-proxy.py —— 节点代理分流（老板规则 2026-09-30）

规则：
  * 模型面板（cc.3602020.xyz / api.office3.pp.ua）→ NO_PROXY 排除 → 直连大陆 IP
  * Telegram → telegram.proxy_url / TELEGRAM_PROXY（显式，不依赖全局变量）
  * 国内站点 → 代理客户端自身的 geo 规则直连
  * GitHub / 国外站点 → 全局代理

做法：启动脚本里保留 HTTP_PROXY/HTTPS_PROXY/ALL_PROXY（缺则补），
      同时确保 NO_PROXY 含本机+内网+面板域名，并补上 TELEGRAM_PROXY。
用法：
  python fix-split-proxy.py                      # 自动探测 run_hermes.bat
  python fix-split-proxy.py --bat <路径>          # 指定
  python fix-split-proxy.py --proxy-port 1089     # 指定代理端口（默认 1089）
"""
import argparse
import glob
import os
import shutil
import subprocess
import sys
import time

PANEL_HOSTS = ["cc.3602020.xyz", "api.office3.pp.ua", ".3602020.xyz", ".office3.pp.ua"]
BASE_NOPROXY = ["localhost", "127.0.0.1", "::1", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]

BAT_CANDS = [
    r"D:\soft\hermes\run_hermes.bat",
    r"D:\Program Files\hermes\run_hermes.bat",
    r"C:\soft\hermes\run_hermes.bat",
    os.path.join(os.environ.get("HERMES_HOME", ""), "run_hermes.bat"),
]

ap = argparse.ArgumentParser()
ap.add_argument("--bat")
ap.add_argument("--proxy-port", default="1089")
a = ap.parse_args()

BAT = a.bat
if not BAT or not os.path.isfile(BAT):
    BAT = next((c for c in BAT_CANDS if c and os.path.isfile(c)), None)
if not BAT:
    print("找不到 run_hermes.bat：")
    for c in BAT_CANDS:
        if c:
            print("   ", c)
    sys.exit(1)

P = a.proxy_port
WANT = {
    "HTTP_PROXY": "http://127.0.0.1:%s" % P,
    "HTTPS_PROXY": "http://127.0.0.1:%s" % P,
    "ALL_PROXY": "socks5://127.0.0.1:%s" % P,
    "NO_PROXY": ",".join(BASE_NOPROXY + PANEL_HOSTS),
    "TELEGRAM_PROXY": "http://127.0.0.1:%s" % P,
}
print("目标启动脚本:", BAT)
src = open(BAT, encoding="utf-8", errors="ignore").read()
lines = src.split("\r\n")
if len(lines) == 1:
    lines = src.split("\n")
bak = "%s.bak-%s" % (BAT, time.strftime("%Y%m%d-%H%M%S"))
shutil.copy2(BAT, bak)
print("备份:", bak)

CRLF = "\r\n" in src
out, seen = [], set()
for ln in lines:
    up = ln.strip().upper()
    hit = next((k for k in WANT if up.startswith('SET "%s=' % k) or up.startswith("SET %s=" % k)), None)
    if hit:
        seen.add(hit)
        newline = 'set "%s=%s"' % (hit, WANT[hit])
        if ln.strip() != newline:
            print("  改: %s  ->  %s" % (ln.strip()[:70], newline))
        out.append(newline)
        continue
    out.append(ln)
missing = [k for k in WANT if k not in seen]
if missing:
    # 插在最后一条 set 之后
    idx = max((i for i, l in enumerate(out) if l.strip().upper().startswith("SET")), default=0)
    for k in missing:
        out.insert(idx + 1, 'set "%s=%s"' % (k, WANT[k]))
        print("  补: set \"%s=%s\"" % (k, WANT[k]))

open(BAT, "w", encoding="utf-8", newline="\r\n" if CRLF else "\n").write("\r\n".join(out) if CRLF else "\n".join(out))
print("\n--- 改后的启动脚本 ---")
for l in open(BAT, encoding="utf-8", errors="ignore").read().splitlines():
    if l.strip():
        print("   " + l)

print("\n--- 自测（本机两条路是否都通）---")
def run(cmd):
    try:
        r = subprocess.run(cmd, capture_output=True, text=True, timeout=40, shell=True)
        return (r.stdout or r.stderr or "").strip().splitlines()[-1:] or [""]
    except Exception as e:
        return ["失败: %s" % e]

prox = "http://127.0.0.1:%s" % P
for label, cmd in (
    ("① 走代理访问 GitHub（应 200/3xx）", 'curl -s -o NUL -w "%%{http_code} %%{time_total}s" -x %s https://github.com' % prox),
    ("② 直连模型面板（应 200/401）", 'curl -s -o NUL -w "%%{http_code} %%{time_total}s" --noproxy "*" https://api.office3.pp.ua:1013/v1/models'),
    ("③ 直连出口 IP（应是大陆 IP）", 'curl -s --max-time 10 --noproxy "*" https://ipinfo.io/ip'),
    ("④ 走代理出口 IP（应是境外）", 'curl -s --max-time 12 -x %s https://ipinfo.io/ip' % prox),
):
    print("  %s -> %s" % (label, " | ".join(run(cmd))))

print("\n完成。**重启节点/云电脑**后新环境才生效。")
