# retoor <retoor@molodetz.nl>

from email.message import EmailMessage

import pytest

from devplacepy.services.email.client import (
    EmailClient,
    _decode_date,
    _header_addresses,
    imap_quote,
)
from devplacepy.services.email.config import EmailAccount
from devplacepy.services.email.errors import EmailError


def _account(**overrides):
    base = {
        "label": "work",
        "imap_host": "127.0.0.1",
        "imap_port": 993,
        "imap_ssl": 1,
        "smtp_host": "127.0.0.1",
        "smtp_port": 587,
        "smtp_starttls": 1,
        "username": "me@example.com",
        "password": "secret",
    }
    base.update(overrides)
    return EmailAccount.from_row(base)


def test_imap_quote_escapes_quotes_and_backslashes():
    assert imap_quote('a"b\\c') == '"a\\"b\\\\c"'


def test_header_addresses_extracts_only_addresses():
    parsed = _header_addresses("Alice <a@x.dev>, b@y.dev")
    assert parsed == ["Alice <a@x.dev>", "b@y.dev"]


def test_header_addresses_empty_is_empty_list():
    assert _header_addresses("") == []


def test_decode_date_parses_rfc2822():
    iso = _decode_date("Wed, 18 Jun 2025 10:30:00 +0000")
    assert iso is not None and iso.startswith("2025-06-18T10:30:00")


def test_decode_date_returns_raw_on_unparseable():
    assert _decode_date("not a date") == "not a date"


def test_decode_date_empty_is_none():
    assert _decode_date("") is None


def test_imap_without_host_raises_config_error():
    client = EmailClient(_account(imap_host=""))
    with pytest.raises(EmailError) as exc:
        client.list_folders()
    assert exc.value.kind == "config"


def test_smtp_without_host_raises_config_error():
    client = EmailClient(_account(smtp_host=""))
    with pytest.raises(EmailError) as exc:
        client.send_message(to=["x@y.dev"], subject="hi", body="b")
    assert exc.value.kind == "config"


def test_imap_loopback_host_is_blocked():
    client = EmailClient(_account(imap_host="127.0.0.1"))
    with pytest.raises(EmailError) as exc:
        client.list_folders()
    assert exc.value.kind == "blocked"


def test_smtp_loopback_host_is_blocked():
    client = EmailClient(_account(smtp_host="127.0.0.1"))
    with pytest.raises(EmailError) as exc:
        client.send_message(to=["x@y.dev"], subject="hi", body="b")
    assert exc.value.kind == "blocked"


def test_render_message_truncates_oversized_body():
    client = EmailClient(_account())
    message = EmailMessage()
    message["From"] = "Alice <a@x.dev>"
    message["To"] = "b@y.dev"
    message["Subject"] = "topic"
    message.set_content("x" * 200_000)
    rendered = client._render_message("17", "INBOX", ["\\Seen"], message)
    assert rendered["body_truncated"] is True
    assert len(rendered["body"]) == 80_000
    assert rendered["uid"] == "17"
    assert rendered["to"] == ["b@y.dev"]


def test_render_message_lists_attachments():
    client = EmailClient(_account())
    message = EmailMessage()
    message["From"] = "a@x.dev"
    message["Subject"] = "with attachment"
    message.set_content("body")
    message.add_attachment(
        b"payload", maintype="application", subtype="pdf", filename="report.pdf"
    )
    rendered = client._render_message("3", "INBOX", [], message)
    assert rendered["body"] == "body"
    assert rendered["attachments"][0]["filename"] == "report.pdf"
    assert rendered["attachments"][0]["content_type"] == "application/pdf"
