import urllib.request, time, hashlib, re, os, subprocess
from curl_cffi import requests

def solve_challenge(html):
    m = re.search(r"\['([A-F0-9]{40})'", html)
    if not m: return None, None
    c = m.group(1)
    n1 = int(c[0], 16)
    i = 0
    t0 = time.time()
    while True:
        d = hashlib.sha1((c + str(i)).encode()).digest()
        if d[n1] == 0xb0 and d[n1+1] == 0x0b: break
        i += 1
    return c + str(i), f"{time.time() - t0:.3f}"

yaml_config = """
mode: global
mixed-port: 10899
bind-address: '127.0.0.1'
proxies:
"""
proxy_str = ""
with open("proxies.txt") as f:
    for line in f:
        if "ss," in line:
            proxy_str = line.strip()
            break
parts = proxy_str.split("=", 1)
cfg = parts[1].strip().split(",")
params = dict(p.strip().split("=", 1) for p in cfg[3:] if "=" in p)
yaml_config += f"""  - name: "test"
    type: ss
    server: "{cfg[1].strip()}"
    port: {cfg[2].strip()}
    cipher: "{params.get('encrypt-method', '')}"
    password: "{params.get('password', '')}"
"""
if "obfs" in params:
    yaml_config += f"    plugin: obfs\n    plugin-opts:\n      mode: {params['obfs']}\n      host: {params['obfs-host']}\n"
with open("test_503.yaml", "w") as f: f.write(yaml_config)

proc = subprocess.Popen(["./.venv/bin/mihomo", "-f", "test_503.yaml"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
time.sleep(2)

s = requests.Session()
p = {"http": "socks5://127.0.0.1:10899", "https": "socks5://127.0.0.1:10899"}

try:
    with open("test_503.log", "w") as out:
        ip_resp = s.get("http://httpbin.org/ip", proxies=p, impersonate="chrome", timeout=5)
        out.write(f"Proxy IP: {ip_resp.json()['origin']}\n")
        
        r1 = s.get("https://zlib.li/", proxies=p, impersonate="chrome", timeout=10)
        out.write(f"Index status: {r1.status_code}\n")
        
        if r1.status_code == 503 and "Checking your browser" in r1.text:
            ct, cti = solve_challenge(r1.text)
            if ct:
                s.cookies.set("c_token", ct, domain="zlib.li", path="/")
                s.cookies.set("c_time", cti, domain="zlib.li", path="/")
                r1 = s.get("https://zlib.li/", proxies=p, impersonate="chrome", timeout=10)
                out.write(f"Index status after PoW: {r1.status_code}\n")
        
        r2 = s.get("https://zlib.li/s/Project", proxies=p, impersonate="chrome", timeout=10)
        out.write(f"Search status: {r2.status_code}\n")
        
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(r2.text, "lxml")
        card = soup.find("z-bookcard")
        if card and card.get("download"):
            dl = card.get("download")
            out.write(f"Got dl path: {dl}\n")
            r3 = s.get("https://zlib.li" + dl, proxies=p, impersonate="chrome", allow_redirects=True, timeout=10)
            out.write(f"Download status: {r3.status_code}\n")
            if r3.status_code == 503:
                if "Checking your browser" in r3.text:
                    ct, cti = solve_challenge(r3.text)
                    if ct:
                        s.cookies.set("c_token", ct, domain="zlib.li", path="/")
                        s.cookies.set("c_time", cti, domain="zlib.li", path="/")
                        r4 = s.get("https://zlib.li" + dl, proxies=p, impersonate="chrome", allow_redirects=True, timeout=10)
                        out.write(f"Retry status: {r4.status_code}\n")
                        with open("test_503_body.html", "w") as f2: f2.write(r4.text)
                else:
                    out.write("Not PoW 503\n")
finally:
    proc.terminate()
