#!/usr/bin/env python3
"""Download TNG eWallet XAPK from Uptodown eAPI (arm64-v8a)."""
from __future__ import annotations

import json
import re
import subprocess
import sys
import urllib.request
import zipfile
from pathlib import Path

UA = "Mozilla/5.0 (Linux; Android 13) Chrome/120.0.0.0 Mobile Safari/537.36"
APP_CODE = "1000382462"
VERSION = "1.9.10"
ARCH = "arm64-v8a, armeabi-v7a, x86_64"
BASE = "https://touch-n-go-ewallet.en.uptodown.com"
OUT_XAPK = Path("reverse/dumps/tng_1.9.10.xapk")
OUT_DIR = Path("reverse/dumps/tng_xapk_extracted")


def fetch(url: str) -> bytes:
    req = urllib.request.Request(url, headers={"User-Agent": UA})
    with urllib.request.urlopen(req, timeout=120) as resp:
        return resp.read()


def fetch_text(url: str) -> str:
    return fetch(url).decode("utf-8", "ignore")


def main() -> int:
    versions = json.loads(fetch_text(f"{BASE}/android/apps/{APP_CODE}/versions/1"))
    entry = next(x for x in versions["data"] if x["version"] == VERSION)
    version_id = entry["versionURL"]["versionID"]
    print(f"version {VERSION} fileID={entry['fileID']} kind={entry['kindFile']}")

    dl_page = fetch_text(f"{BASE}/android/download/{version_id}")
    m = re.search(r'class="button variants" data-version="(\d+)"', dl_page)
    if not m:
        print("variants data-version not found", file=sys.stderr)
        return 1
    data_version = m.group(1)
    print("data_version", data_version)

    files_json = json.loads(fetch_text(f"{BASE}/app/{APP_CODE}/version/{data_version}/files"))
    content = files_json.get("content", "")
    # parse variant rows from HTML fragment
    rows = re.findall(
        r'class="variant".*?data-file-id="(\d+)".*?<span>([^<]+)</span>',
        content,
        flags=re.S,
    )
    if not rows:
        # fallback: any data-file-id near xapk
        rows = re.findall(r'data-file-id="(\d+)"', content)
        rows = [(rid, "?") for rid in rows]
    print("variants", rows)

    target_file_id = None
    for fid, arch in rows:
        if ARCH in arch or "arm64-v8a" in arch:
            target_file_id = fid
            print("pick", fid, arch)
            break
    if not target_file_id and rows:
        target_file_id = rows[0][0]
        print("fallback file_id", target_file_id)

    if not target_file_id:
        print("no file id", file=sys.stderr)
        return 1

    variant_page = fetch_text(f"{BASE}/android/download/{target_file_id}-x")
    token_m = re.search(r'id="detail-download-button"[^>]*data-url="(-[^"]+)"', variant_page)
    if not token_m:
        token_m = re.search(r'data-url="(-[^"]+)"', variant_page)
    if not token_m:
        print("download token not found", file=sys.stderr)
        return 1
    token = token_m.group(1)

    print("downloading XAPK...")
    data = fetch(f"https://dw.uptodown.com/dwn/{token}")
    OUT_XAPK.write_bytes(data)
    print("saved", OUT_XAPK, "bytes", len(data))

    with zipfile.ZipFile(OUT_XAPK) as z:
        apks = [n for n in z.namelist() if n.endswith(".apk")]
        print("apk splits", apks)
        if not apks:
            print("no apk inside xapk", file=sys.stderr)
            return 1

    if OUT_DIR.exists():
        import shutil
        shutil.rmtree(OUT_DIR)
    OUT_DIR.mkdir(parents=True)
    import zipfile as zf
    with zf.ZipFile(OUT_XAPK) as z:
        z.extractall(OUT_DIR)

    apk_files = sorted(OUT_DIR.rglob("*.apk"))
    adb = r"C:\Users\Administrator\AppData\Local\Android\Sdk\platform-tools\adb.exe"
    cmd = [adb, "install-multiple", "-r"] + [str(p) for p in apk_files]
    print("install:", " ".join(cmd))
    r = subprocess.run(cmd, capture_output=True, text=True)
    print(r.stdout)
    print(r.stderr)
    return 0 if r.returncode == 0 else r.returncode


if __name__ == "__main__":
    raise SystemExit(main())
