#!/usr/bin/env python3
"""Automate TNG login/register tap test and report crashes."""
import re
import subprocess
import sys
import time

PKG = "my.com.tngdigital.ewallet"
TAGS = re.compile(
    r"FATAL EXCEPTION|AndroidRuntime.*Process: " + PKG
    + r"|has died|exited due to signal|vhvlnqgy\.bd|blocked killProcess|blocked System\.exit"
    + r"|UserRegistration|UserOtp|UserLogin|Displayed.*tngdigital|ACT on(Create|Resume)"
    + r"|TngExitGuard.*ABRT|TngRoot hooked 6 vhvlnqgy\.R",
    re.I,
)

TAPS = [
    ("register_continue", 540, 959, 8),
    ("maybe_otp_continue", 540, 959, 6),
    ("back_to_login", None, None, 2),
    ("login_tab", 540, 1168, 5),
]


def adb(*args, timeout=30):
    cmd = ["adb"] + list(args)
    r = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
    out = (r.stdout or "") + (r.stderr or "")
    return r.returncode, out.strip()


def pid_alive():
    code, out = adb("shell", "pidof", PKG)
    return code == 0 and out.strip().split()


def top_activity():
    code, out = adb("shell", "dumpsys", "activity", "activities")
    if code != 0:
        return "?"
    for line in out.splitlines():
        if "topResumedActivity=" in line:
            m = re.search(r"/([^/]+)$", line.strip())
            if m:
                return m.group(1).rstrip("}")
            return line.strip()
    return "?"


def logcat_since(start):
    code, out = adb("shell", "logcat", "-d", "-t", start)
    hits = []
    if code == 0:
        for line in out.splitlines():
            if TAGS.search(line):
                hits.append(line)
    return hits


def main():
    adb("logcat", "-c")
    adb("shell", "am", "force-stop", PKG)
    time.sleep(1)
    adb("shell", "am", "start", "-n", f"{PKG}/.ui.SplashActivity")
    time.sleep(12)
    print("=== after cold start ===")
    print("pids:", pid_alive())
    print("activity:", top_activity())

    # dismiss country picker if open
    adb("shell", "input", "keyevent", "KEYCODE_BACK")
    time.sleep(1)

    results = []
    for name, x, y, wait_s in TAPS:
        if x is not None:
            adb("shell", "input", "tap", str(x), str(y))
            print(f"\n=== tap {name} ({x},{y}) ===")
        else:
            adb("shell", "input", "keyevent", "KEYCODE_BACK")
            print(f"\n=== {name} ===")
        time.sleep(wait_s)
        pids = pid_alive()
        act = top_activity()
        crash_buf = adb("shell", "logcat", "-d", "-b", "crash", "-t", "50")[1]
        fatal = [l for l in crash_buf.splitlines() if PKG in l or "vhvlnqgy" in l]
        results.append((name, pids, act, fatal))
        print("pids:", pids or "DEAD")
        print("activity:", act)
        if fatal:
            print("CRASH:", fatal[-3:])

    print("\n=== summary ===")
    ok = True
    for name, pids, act, fatal in results:
        status = "OK" if pids and not fatal else "FAIL"
        if status == "FAIL":
            ok = False
        print(f"{status} {name}: pids={pids} activity={act} crash_lines={len(fatal)}")

    hits = logcat_since("2000")
    print(f"\n=== key log lines ({len(hits)}) ===")
    for line in hits[-40:]:
        print(line)

    return 0 if ok else 1


if __name__ == "__main__":
    sys.exit(main())
