import sys, os, re, json, ctypes, requests
from functools import cmp_to_key
from urllib.parse import quote

if os.name == "nt":
    _strcmp = ctypes.windll.shlwapi.StrCmpLogicalW
    _strcmp.argtypes, _strcmp.restype = [ctypes.c_wchar_p, ctypes.c_wchar_p], ctypes.c_int
    def _cmp_name(a, b): return _strcmp(str(a), str(b))
else:
    def _alphanum_key(s): return [int(x) if x.isdigit() else x.lower() for x in re.split(r'(\d+)', s)]
    def _cmp_name(a, b):
        ka, kb = _alphanum_key(a), _alphanum_key(b)
        return (ka > kb) - (ka < kb)

API = "http://127.0.0.1:5001/api/v0"
session = requests.Session() 

def ipfs(endpoint, arg):
    r = session.post(f"{API}/{endpoint}?arg={quote(arg)}")
    r.raise_for_status()
    return r.json()

def check_cid(cid):
    try:
        res = ipfs("cid/format", cid)
        return not res.get("ErrorMsg", ""), res
    except Exception as e:
        return False, str(e)

def fetch_tree(cid, path="/", name=""):
    print(path)
    links = ipfs("ls", f"{cid}{path if path != '/' else ''}").get("Objects", [{}])[0].get("Links", [])
    children = []
    for e in links:
        if e["Type"] == 1:  # 文件夹
            children.append(fetch_tree(cid, f"{path.rstrip('/')}/{e['Name']}", e["Name"]))
        else:
            children.append([e["Name"], int(e["Size"])])
    # 目录优先 + 自然排序
    children.sort(key=cmp_to_key(lambda a,b:
        -1 if isinstance(a[-1], list) and not isinstance(b[-1], list)
        else 1 if not isinstance(a[-1], list) and isinstance(b[-1], list)
        else _cmp_name(a[0], b[0])
    ))
    return [name, children]

def main():
    if len(sys.argv) < 2:
        print("Usage: python cid.py <CID>")
        sys.exit(1)
    cid = sys.argv[1]
    ok, info = check_cid(cid)
    if not ok:
        print(f"❌ Invalid CID: {info}")
        sys.exit(1)

    print("✅ CID format is valid, starting to fetch the tree")
    tree = fetch_tree(cid)
    tree[0] = ""
    os.makedirs("static", exist_ok=True)
    with open("static/data.json", "w", encoding="utf-8") as f:
        json.dump(tree, f, ensure_ascii=False, separators=(",", ":"))
    print("✅ Data has been exported to static/data.json")

if __name__ == "__main__":
    main()