#!/usr/bin/env python3
"""Regression test for insert_email: a parsed email with no Reply-To header (reply_to=None)
must not crash the recipients loop. This bug (`for a in parsed.get('reply_to', [])` returning
None because the key is present with value None) aborted the whole Gmail backfill on the first
email lacking a Reply-To header. Synthetic data only (guardrail #9).
Run: cd backend && python3 email_integration/test_insert_email.py
"""
import os
import sqlite3
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from email_integration import db as edb  # noqa: E402

FAILS = []


def check(cond, msg):
    print(("  PASS " if cond else "  FAIL ") + msg)
    if not cond:
        FAILS.append(msg)


def fresh_conn():
    conn = sqlite3.connect(":memory:")
    conn.row_factory = sqlite3.Row
    edb.apply_migrations(conn.cursor())
    return conn


def main():
    # 1) the exact crash case: no Reply-To header -> reply_to is None
    conn = fresh_conn()
    parsed = {
        "rfc_message_id": "<m1@example.com>",
        "from_email": "lp@example.com", "from_name": "An LP",
        "sent_at": "2026-05-01T10:00:00Z", "subject": "Re: the fund",
        "to": [{"email": "grant@ten31.xyz", "name": "Grant"}],
        "cc": [], "bcc": [], "references": [],
        "reply_to": None,            # <-- previously crashed: 'NoneType' object is not iterable
        "body_text": "Some concern about lock-up.",
    }
    try:
        eid = edb.insert_email(conn, parsed=parsed, match_status="unmatched")
        ok = bool(eid)
    except TypeError as e:
        ok = False
        print("  (raised)", e)
    check(ok, "insert_email with reply_to=None does not raise")
    if ok:
        kinds = sorted(r["kind"] for r in conn.execute("SELECT kind FROM email_recipients WHERE email_id=?", (eid,)))
        check(kinds == ["from", "to"], f"recipients are from+to, reply_to skipped (got {kinds})")

    # 2) defensive: every address field present-but-None must not crash either
    conn2 = fresh_conn()
    parsed2 = {
        "rfc_message_id": "<m2@example.com>", "from_email": "x@example.com",
        "sent_at": "2026-05-02T10:00:00Z",
        "to": None, "cc": None, "bcc": None, "references": None, "reply_to": None,
        "body_text": "no recipients parsed",
    }
    try:
        eid2 = edb.insert_email(conn2, parsed=parsed2, match_status="unmatched")
        ok2 = bool(eid2)
    except TypeError as e:
        ok2 = False
        print("  (raised)", e)
    check(ok2, "insert_email with all recipient fields None does not raise")

    # 3) the happy path still records a real Reply-To
    conn3 = fresh_conn()
    parsed3 = dict(parsed, rfc_message_id="<m3@example.com>", reply_to="replies@example.com")
    eid3 = edb.insert_email(conn3, parsed=parsed3, match_status="matched")
    rt = conn3.execute("SELECT address FROM email_recipients WHERE email_id=? AND kind='reply_to'", (eid3,)).fetchone()
    check(rt and rt["address"] == "replies@example.com", "a present Reply-To is still recorded")

    if FAILS:
        print(f"\nFAILED ({len(FAILS)})")
        for f in FAILS:
            print("  - " + f)
        sys.exit(1)
    print("\nALL PASS (insert_email reply_to/None regression)")


if __name__ == "__main__":
    main()
