import json
import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.utils import formataddr

from flask import Blueprint, request

from app.utils import log_util, config_util, cache_util

mod = Blueprint('email', __name__)
logger = log_util.logger()


@mod.route('/send', methods=['POST'])
def send():
    data = request.json
    address = data.get("address")
    title = data.get("title")
    content = data.get("content")
    pusher = data.get("pusher", "")
    if not address or not title or not content:
        return json.dumps({
            "code": 400,
            "message": "缺失必填参数",
            "data": None
        })
    try:
        if _rate_limit(address):
            return json.dumps({
                "code": 400,
                "message": "发送过于频繁，请等待60秒后再试",
                "data": None
            })
        logger.info("email send param: {}".format(request.get_data()))
        _send_mail(address, title, content, pusher)
        return json.dumps({
            "code": 200,
            "message": "",
            "data": None
        })
    except BaseException as e:
        logger.exception("email send fail ")
        return json.dumps({
            "code": 500,
            "message": str(e),
            "data": None
        })


def _send_mail(address: str, title: str, content: str, pusher=""):
    conf = config_util.get(f"email_{pusher}", None)
    if conf is None:
        if pusher != "":
            raise RuntimeError("发送者邮箱不支持：{}".format(pusher))
        conf = config_util.get("email")
    msg = MIMEText(content, 'html', 'utf-8')
    msg['Subject'] = Header(title, 'utf-8')
    msg['From'] = formataddr((Header(conf.get("from"), 'utf-8').encode(), conf.get("smtp_username")))
    msg['To'] = address

    # Send the message via our own SMTP server.
    s = smtplib.SMTP_SSL(conf.get("smtp_host"), port=conf.get("smtp_port"))
    s.login(conf.get("smtp_username"), conf.get("smtp_password"))
    s.sendmail(conf.get("smtp_username"), address, msg.as_string())
    s.quit()


def _rate_limit(addr: str) -> bool:
    key = "email#limit#{}".format(addr)
    if cache_util.get(key, False):
        return True
    cache_util.set(key, True, ttl=60)
    return False
