#!/usr/bin/env python3
"""Check IMAP inbox for bounce-back / delivery-failure emails.

Silent (exit 0 with no output) when nothing to report.
Outputs summary when bounces are found.
"""

import imaplib
import email
import os
import sys
from datetime import datetime, timedelta, timezone

HOST = "mail.germainebrown.com"
PORT = 993
USER = "g@germainebrown.com"
PW_FILE = "/root/.config/himalaya/g-germainebrown.pass"
CHECK_HOURS = 24

BOUNCE_KEYWORDS = [
    "mail delivery failed", "delivery status notification", "undelivered",
    "returned mail", "mail delivery failure", "non-delivery",
    "delivery failed", "undeliverable", "delivery report",
    "returned to sender", "message bounced",
]

BOUNCE_SENDERS = [
    "mailer-daemon", "postmaster", "mail delivery system",
]


def safe_str(val):
    if val is None:
        return ""
    if isinstance(val, str):
        return val
    try:
        return str(val)
    except Exception:
        return ""


def is_bounce(msg):
    subject = safe_str(msg.get("Subject", "")).lower()
    sender = safe_str(msg.get("From", "")).lower()

    for kw in BOUNCE_KEYWORDS:
        if kw in subject:
            return True

    for s in BOUNCE_SENDERS:
        if s in sender:
            return True

    if msg.get_content_type() == "text/plain":
        payload = msg.get_payload(decode=True)
        if payload:
            body = safe_str(payload).lower()
            if "permanent error" in body or "could not be delivered" in body:
                return True
    return False


def main():
    try:
        pw = open(PW_FILE).read().strip()
    except FileNotFoundError:
        print("[SILENT]")
        return

    since = (datetime.now(timezone.utc) - timedelta(hours=CHECK_HOURS)).strftime("%d-%b-%Y")

    try:
        conn = imaplib.IMAP4_SSL(HOST, PORT)
        conn.login(USER, pw)
        conn.select("INBOX")
    except Exception as e:
        print(f"ERROR: IMAP connection failed: {e}")
        sys.exit(1)

    status, data = conn.search(None, f'(SINCE {since})')
    if status != "OK":
        print("[SILENT]")
        conn.logout()
        return

    bounces = []
    for num in data[0].split():
        status, msg_data = conn.fetch(num, "(RFC822)")
        if status != "OK":
            continue
        raw = email.message_from_bytes(msg_data[0][1])
        if is_bounce(raw):
            subject = raw.get("Subject", "(no subject)")
            sender = raw.get("From", "(unknown)")
            date = raw.get("Date", "")
            bounces.append({
                "subject": subject,
                "from": sender,
                "date": date,
                "uid": num.decode(),
            })

    conn.logout()

    if not bounces:
        return

    print(f"📬 {len(bounces)} bounce-back(s) detected in the last {CHECK_HOURS}h:\n")
    for b in bounces:
        print(f"  • {b['subject']}")
        print(f"    From: {b['from']}")
        print(f"    Date: {b['date']}")
        print()


if __name__ == "__main__":
    main()
