"""
ms_sender.py — 邮局发信引擎 (主控 → SMTP认证提交 → 邮局发出)
================================================================
邮局路线说明:
  - 邮局服务器自己完成 MTA 级魔改 (客户端伪装Received/Message-ID重建/DKIM签名/头部剥离)
  - 主控只负责"内容层": 主题垃圾词替换 + 字符集 + ASCII显示名 + 正文
  - 主控不签DKIM (邮局签), 不加伪Received/Feedback-ID等 (邮局会剥)
  - From 显示名必须 ASCII (RFC2047编码的日文名会导致邮局DKIM插件解析失败)
"""
import os
import smtplib
import time
import random
import string
import threading

_THIS_DIR = os.path.dirname(os.path.abspath(__file__))
_PROJECT_ROOT = os.path.dirname(_THIS_DIR)
if _PROJECT_ROOT not in __import__('sys').path:
    __import__('sys').path.insert(0, _PROJECT_ROOT)

# 邮局路线默认ASCII显示名池 (原部署面板同款思路)
DEFAULT_SENDER_NAMES = ['Notice', 'Information', 'Mailer', 'Service', 'Support', 'Customer Center']

_lock = threading.RLock()


def _get_sender(names_pool):
    pool = [n.strip() for n in (names_pool or DEFAULT_SENDER_NAMES) if n.strip()]
    return random.choice(pool) if pool else 'Notice'


def send_one(ms, from_email, sender_name, to_email, subject, html,
             mail_charset='utf-8', avoid_spam_words=True, timeout=30,
             reply_to='', list_unsubscribe=''):
    """通过 SMTP认证 向邮局提交一封邮件
    ms: {ip, smtp_port, smtp_user, smtp_pwd}
    reply_to: 回信地址 (可选)
    list_unsubscribe: 退订链接 (可选)
    返回 (ok, code, msg)
    """
    from core.sender import MailSender
    from core.models import MailBox, Email
    try:
        # 用 core MailSender 构建邮件 (内容层魔改: 垃圾词替换+字符集; 不加伪装头不加DKIM)
        sender = MailSender()
        sender._mail_charset = mail_charset or 'utf-8'
        sender._feature_flags = {'avoid_spam_words': bool(avoid_spam_words),
                                 'personalize_subject': False,
                                 'invisible_segments': False,
                                 'embed_images': False,
                                 'timestamp_personalize': False}
        box = MailBox(enable=True, email=from_email, user=from_email, pwd='',
                      sender_name=sender_name or '', random_user=False)
        em = Email(email_address=to_email)
        headers = None
        if list_unsubscribe:
            headers = {'LIST-UNSUBSCRIBE': list_unsubscribe}
        msg_str = sender._build_message(box, em, subject, html, mail_type=1,
                                        helo_domain=None, sender_name=sender_name,
                                        reply_to=reply_to or None,
                                        custom_headers=headers,
                                        disguise=False, verp_enabled=False,
                                        disguise_opts=None)
        # 解析为 email 对象供 smtplib 发送
        from email.parser import Parser
        msg = Parser().parsestr(msg_str)
        sm = smtplib.SMTP(ms.get('ip'), int(ms.get('smtp_port') or 587), timeout=timeout)
        try:
            code, _resp = sm.ehlo()
            if sm.has_extn('starttls'):
                sm.starttls()
                sm.ehlo()
            sm.login(str(ms.get('smtp_user')), str(ms.get('smtp_pwd') or ''))
            refused = sm.send_message(msg)
            sm.quit()
            if refused:
                return False, '550', str(refused)[:100]
            return True, '250', 'OK'
        except smtplib.SMTPResponseException as e:
            try:
                sm.quit()
            except Exception:
                pass
            return False, str(e.smtp_code), str(e.smtp_error or e)[:100]
        except Exception:
            try:
                sm.quit()
            except Exception:
                pass
            raise
    except Exception as e:
        return False, 'error', str(e)[:120]


def test_connection(ms, timeout=15):
    """测试邮局 SMTP 连接+认证 (不发送)"""
    try:
        sm = smtplib.SMTP(ms.get('ip'), int(ms.get('smtp_port') or 587), timeout=timeout)
        sm.ehlo()
        if sm.has_extn('starttls'):
            sm.starttls()
            sm.ehlo()
        sm.login(str(ms.get('smtp_user')), str(ms.get('smtp_pwd') or ''))
        sm.quit()
        return True, '连接+认证成功'
    except Exception as e:
        return False, str(e)[:120]
