"""List verification-email metadata for device inboxes in one location.

Python 3.9+; standard library only. Supply MAILSLURP_API_KEY privately.
Set DEVICE_TAG, VERIFICATION_SENDER, and VERIFICATION_SUBJECT to your values.
"""
import json
import os
import time
from datetime import datetime, timedelta, timezone
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode, quote
from urllib.request import Request, urlopen

API_BASE = "https://api.mailslurp.com"


def api_json(api_key, path, params=None, method="GET", body=None):
    query = "?" + urlencode(params) if params else ""
    headers = {"x-api-key": api_key, "Accept": "application/json"}
    data = None
    if body is not None:
        headers["Content-Type"] = "application/json"
        data = json.dumps(body).encode("utf-8")
    request = Request(API_BASE + path + query, data=data, headers=headers, method=method)
    try:
        with urlopen(request, timeout=30) as response:
            return json.load(response)
    except HTTPError as error:
        # Do not print response bodies, credentials, or verification messages.
        raise RuntimeError(f"MailSlurp request failed: HTTP {error.code}") from None
    except URLError:
        raise RuntimeError("MailSlurp connection failed") from None


def iter_pages(api_key, path, **filters):
    page = 0
    while True:
        result = api_json(api_key, path, {**filters, "page": page, "size": 20, "sort": "ASC"})
        items = result["content"]
        yield from items
        if not items or result.get("last") is True:
            return
        page += 1
        time.sleep(0.2)


def list_verification_emails(api_key, tag, sender, subject_text, since, before):
    # Freeze the upper time bound while walking pages; totals can be -1.
    for inbox in iter_pages(api_key, "/inboxes/paginated", tag=tag, before=before):
        inbox_id = quote(inbox["id"], safe="")
        path = f"/inboxes/{inbox_id}/emails/paginated"
        for email in iter_pages(api_key, path, since=since, before=before):
            if (email.get("from") or "").casefold() != sender.casefold():
                continue
            if subject_text.casefold() not in (email.get("subject") or "").casefold():
                continue
            # IDs let an authorized operator open the email without logging its code or link.
            yield {
                "inboxId": inbox["id"],
                "emailId": email["id"],
                "receivedAt": email["createdAt"],
            }


def main():
    api_key = os.environ.get("MAILSLURP_API_KEY")
    if not api_key:
        raise SystemExit("Set MAILSLURP_API_KEY in your environment or secret manager")
    tag = os.environ.get("DEVICE_TAG", "site-auckland")
    sender = os.environ.get("VERIFICATION_SENDER", "accounts@device-vendor.example")
    subject_text = os.environ.get("VERIFICATION_SUBJECT", "Verify your email")
    now = datetime.now(timezone.utc)
    before = now.isoformat().replace("+00:00", "Z")
    since = (now - timedelta(days=1)).isoformat().replace("+00:00", "Z")
    try:
        for record in list_verification_emails(api_key, tag, sender, subject_text, since, before):
            print(json.dumps(record))
    except RuntimeError as error:
        raise SystemExit(str(error)) from None


if __name__ == "__main__":
    main()
