from typing import Tuple
from typing import Union
import re
import tempfile


def queue_email(app, subj, body, respond_to) -> Tuple[bool, Union[str, int]]:
    """
    Queues an email to be sent. First port of entry for ANY email.
    If email is suspected to be spam, write it to a temp file.
    Spam files will be deleted upon termination of the app.

    If succeeded, returns tuple (True, position_in_queue: int)

    If failed, returns tuple (False, path_to_tempfile: str)
    """

    def has_spam_words(body: str) -> bool:
        return " SEO " in body or "subscribe" in body or "click here" in body.lower()

    def write_email(out, subj, body, respond_to):
        """Write email somewhere instead of sending it"""
        out(f"/* SUBJECT: {subj}")
        out(str(body))
        out(f"REPLY-TO: {respond_to}")
        out("*/ end of email")

    emails_in_body = re.findall(
        r"([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)", body
    )
    if emails_in_body or has_spam_words(body):
        # genuine human beings know that email has its own form field
        # assume only desperate spammers are going to include it twice
        fd, path = tempfile.mkstemp(dir=app.config["SPAM_DIR"], text=True)
        with open(fd, "w") as f:
            write_email(lambda msg: f.write(f"{msg}\n"), subj, body, respond_to)
        return False, path

    app.email_queue.put((subj, body, respond_to))
    app.logger.warning(f"Queuing a new email with subject {subj}")
    n = app.email_queue.qsize()
    if n > 1:
        app.logger.warning(f"The email queue has {n} messages in it")
        app.logger.warning(f"Newly queued email is below:")
        write_email(app.logger.warning, subj, body, respond_to)
    return True, n