#!/usr/bin/env python3
"""Capture the MS TOTP setup key from the current 'Can't scan' dialog and store it
securely. The secret is NEVER printed in full and NEVER written to any file other
than the 0600 credentials env. Prints only last-4 chars + account name for sanity.
"""
import json, sys, os, re, time
sys.path.insert(0, "/home/claude/repos/openclaw/.claude/skills/advancedmd/scripts")
import amd_browser as A

CREDS = "/home/claude/.config/amd-agent/credentials.env"
MS_HOSTS = ("mysignins.microsoft.com", "login.microsoftonline.com")


def attach():
    pages = A.list_pages()
    t = None
    for p in pages:
        if any(h in (p.get("url") or "") for h in MS_HOSTS):
            t = p; break
    if not t:
        t = pages[0]
    pg = A.attach(t); pg.enable()
    return pg


def main():
    pg = attach()
    # The 'Can't scan' panel shows a secret key and a URL. Grab full body innerText.
    body = pg.eval("(document.body&&document.body.innerText||'')") or ""
    secret = None
    # Prefer the value on the line after a 'Secret key:' label.
    m = re.search(r'[Ss]ecret key:?\s*\n?\s*([A-Za-z2-7][A-Za-z2-7 ]{14,70})', body)
    if m:
        cand = re.sub(r'\s+', '', m.group(1)).upper()
        if 16 <= len(cand) <= 64 and re.fullmatch(r'[A-Z2-7]+', cand):
            secret = cand
    if not secret:
        # base32 secret (case-insensitive): A-Z a-z 2-7, 16-64 chars after stripping spaces.
        candidates = re.findall(r'(?:[A-Za-z2-7]{4}\s*){3,}[A-Za-z2-7]{2,8}', body)
        if not candidates:
            candidates = re.findall(r'[A-Za-z2-7]{16,64}', body.replace(" ", ""))
        for c in candidates:
            cand = re.sub(r'\s+', '', c).upper()
            if 16 <= len(cand) <= 64 and re.fullmatch(r'[A-Z2-7]+', cand):
                secret = cand; break
    # account name (issuer:account) sometimes shown
    acct = ""
    m = re.search(r'(account name|Account name)[:\s]+([^\n]+)', body)
    if m:
        acct = m.group(2).strip()[:60]
    if not secret:
        # dump a SANITIZED hint (no secret) for debugging: show lines, masking base32
        masked = re.sub(r'[A-Za-z2-7]{4,}', lambda mm: mm.group(0)[:1] + '***', body)
        with open("/tmp/amdwork/capture_debug.txt", "w") as f:
            f.write(masked[:2000])
        print("CAPTURE_FAIL no base32 found; sanitized dump -> /tmp/amdwork/capture_debug.txt")
        pg.close(); return
    # store securely
    os.makedirs(os.path.dirname(CREDS), exist_ok=True)
    # remove any prior AGENT_MS_TOTP_SECRET line, then append
    lines = []
    if os.path.exists(CREDS):
        with open(CREDS) as f:
            lines = [l for l in f if not l.startswith("AGENT_MS_TOTP_SECRET=")]
    lines.append("AGENT_MS_TOTP_SECRET=%s\n" % secret)
    with open(CREDS, "w") as f:
        f.writelines(lines)
    os.chmod(CREDS, 0o600)
    # scrub any debug file that may contain the secret
    for junk in ("/tmp/amdwork/capture_debug.txt",):
        try:
            if os.path.exists(junk):
                os.remove(junk)
        except Exception:
            pass
    print("CAPTURE_OK len=%d last4=%s acct=%r stored=%s" % (len(secret), secret[-4:], acct, CREDS))
    pg.close()


if __name__ == "__main__":
    main()
