"""
Notification email machinery, for tasks to send credentials and instructions to users.

Email templates placed inside the `templates` directory of this module should:

- extend from `layout`
- provide `subject` and `body` blocks
"""

from enum import Enum
import os.path

from jinja2 import Environment, FileSystemLoader

from sqlalchemy.orm import Session as SQLA_SESSION

from srcf.database import Member, Society
from srcf.mail import send_mail

from ..plumbing import Owner, owner_desc, owner_name, owner_website


ENV = Environment(loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), "templates")),
                  trim_blocks=True, lstrip_blocks=True)

ENV.filters.update({"is_member": lambda mem: isinstance(mem, Member),
                    "is_society": lambda soc: isinstance(soc, Society),
                    "owner_name": owner_name,
                    "owner_desc": owner_desc,
                    "owner_website": owner_website})


CURRENT_WRAPPER = None


class Layout(Enum):
    """
    Base layout template to be inherited by an email-specific template.
    """

    SUBJECT = "/common/subject.j2"
    """
    Subject line of the email.
    """
    BODY = "/common/body.j2"
    """
    Main content of the email.
    """


class EmailWrapper:
    """
    Context manager for email sending, used to augment emails with additional metadata.
    """

    def __init__(self, subject: str=None, body: str=None, context: dict=None):
        self._layouts = {Layout.SUBJECT: subject,
                         Layout.BODY: body}
        self._context = context

    def render(self, template: str, layout: Layout, target: Owner, context: dict=None):
        """
        Render an email template with Jinja using the provided context.
        """
        context = dict(context or (), layout=layout.value, target=target)
        out = ENV.get_template(template).render(context)
        custom = self._layouts.get(layout)
        if custom:
            if self._context:
                context.update(self._context)
            out = custom.format(out, **context)
        if layout == Layout.SUBJECT:
            out = " ".join(out.split())
        return out

    def __enter__(self):
        global CURRENT_WRAPPER
        if CURRENT_WRAPPER:
            raise RuntimeError("Another context is already active")
        CURRENT_WRAPPER = self

    def __exit__(self, exception_type, exception_value, traceback):
        global CURRENT_WRAPPER
        CURRENT_WRAPPER = None


DEFAULT_WRAPPER = EmailWrapper(subject="[SRCF] {}")


def send(target: Owner, template: str, context: dict=None, session: SQLA_SESSION=None):
    """
    Render and send an email to the target member or society.
    """
    wrapper = CURRENT_WRAPPER or DEFAULT_WRAPPER
    subject = wrapper.render(template, Layout.SUBJECT, target, context)
    body = wrapper.render(template, Layout.BODY, target, context)
    recipient = (owner_desc(target, True), target.email)
    send_mail(recipient, subject, body, copy_sysadmins=False, session=session)

31dbe236f3e990f99aa451c383da99dcd6ad4212
<mask token>


class Layout(Enum):
    <mask token>
    SUBJECT = '/common/subject.j2'
    <mask token>
    BODY = '/common/body.j2'
    <mask token>


class EmailWrapper:
    """
    Context manager for email sending, used to augment emails with additional metadata.
    """

    def __init__(self, subject: str=None, body: str=None, context: dict=None):
        self._layouts = {Layout.SUBJECT: subject, Layout.BODY: body}
        self._context = context

    def render(self, template: str, layout: Layout, target: Owner, context:
        dict=None):
        """
        Render an email template with Jinja using the provided context.
        """
        context = dict(context or (), layout=layout.value, target=target)
        out = ENV.get_template(template).render(context)
        custom = self._layouts.get(layout)
        if custom:
            if self._context:
                context.update(self._context)
            out = custom.format(out, **context)
        if layout == Layout.SUBJECT:
            out = ' '.join(out.split())
        return out

    def __enter__(self):
        global CURRENT_WRAPPER
        if CURRENT_WRAPPER:
            raise RuntimeError('Another context is already active')
        CURRENT_WRAPPER = self

    def __exit__(self, exception_type, exception_value, traceback):
        global CURRENT_WRAPPER
        CURRENT_WRAPPER = None


<mask token>

<mask token>


class Layout(Enum):
    """
    Base layout template to be inherited by an email-specific template.
    """
    SUBJECT = '/common/subject.j2'
    """
    Subject line of the email.
    """
    BODY = '/common/body.j2'
    """
    Main content of the email.
    """


class EmailWrapper:
    """
    Context manager for email sending, used to augment emails with additional metadata.
    """

    def __init__(self, subject: str=None, body: str=None, context: dict=None):
        self._layouts = {Layout.SUBJECT: subject, Layout.BODY: body}
        self._context = context

    def render(self, template: str, layout: Layout, target: Owner, context:
        dict=None):
        """
        Render an email template with Jinja using the provided context.
        """
        context = dict(context or (), layout=layout.value, target=target)
        out = ENV.get_template(template).render(context)
        custom = self._layouts.get(layout)
        if custom:
            if self._context:
                context.update(self._context)
            out = custom.format(out, **context)
        if layout == Layout.SUBJECT:
            out = ' '.join(out.split())
        return out

    def __enter__(self):
        global CURRENT_WRAPPER
        if CURRENT_WRAPPER:
            raise RuntimeError('Another context is already active')
        CURRENT_WRAPPER = self

    def __exit__(self, exception_type, exception_value, traceback):
        global CURRENT_WRAPPER
        CURRENT_WRAPPER = None


<mask token>


def send(target: Owner, template: str, context: dict=None, session:
    SQLA_SESSION=None):
    """
    Render and send an email to the target member or society.
    """
    wrapper = CURRENT_WRAPPER or DEFAULT_WRAPPER
    subject = wrapper.render(template, Layout.SUBJECT, target, context)
    body = wrapper.render(template, Layout.BODY, target, context)
    recipient = owner_desc(target, True), target.email
    send_mail(recipient, subject, body, copy_sysadmins=False, session=session)

<mask token>
ENV.filters.update({'is_member': lambda mem: isinstance(mem, Member),
    'is_society': lambda soc: isinstance(soc, Society), 'owner_name':
    owner_name, 'owner_desc': owner_desc, 'owner_website': owner_website})
<mask token>


class Layout(Enum):
    """
    Base layout template to be inherited by an email-specific template.
    """
    SUBJECT = '/common/subject.j2'
    """
    Subject line of the email.
    """
    BODY = '/common/body.j2'
    """
    Main content of the email.
    """


class EmailWrapper:
    """
    Context manager for email sending, used to augment emails with additional metadata.
    """

    def __init__(self, subject: str=None, body: str=None, context: dict=None):
        self._layouts = {Layout.SUBJECT: subject, Layout.BODY: body}
        self._context = context

    def render(self, template: str, layout: Layout, target: Owner, context:
        dict=None):
        """
        Render an email template with Jinja using the provided context.
        """
        context = dict(context or (), layout=layout.value, target=target)
        out = ENV.get_template(template).render(context)
        custom = self._layouts.get(layout)
        if custom:
            if self._context:
                context.update(self._context)
            out = custom.format(out, **context)
        if layout == Layout.SUBJECT:
            out = ' '.join(out.split())
        return out

    def __enter__(self):
        global CURRENT_WRAPPER
        if CURRENT_WRAPPER:
            raise RuntimeError('Another context is already active')
        CURRENT_WRAPPER = self

    def __exit__(self, exception_type, exception_value, traceback):
        global CURRENT_WRAPPER
        CURRENT_WRAPPER = None


<mask token>


def send(target: Owner, template: str, context: dict=None, session:
    SQLA_SESSION=None):
    """
    Render and send an email to the target member or society.
    """
    wrapper = CURRENT_WRAPPER or DEFAULT_WRAPPER
    subject = wrapper.render(template, Layout.SUBJECT, target, context)
    body = wrapper.render(template, Layout.BODY, target, context)
    recipient = owner_desc(target, True), target.email
    send_mail(recipient, subject, body, copy_sysadmins=False, session=session)

<mask token>
ENV = Environment(loader=FileSystemLoader(os.path.join(os.path.dirname(
    __file__), 'templates')), trim_blocks=True, lstrip_blocks=True)
ENV.filters.update({'is_member': lambda mem: isinstance(mem, Member),
    'is_society': lambda soc: isinstance(soc, Society), 'owner_name':
    owner_name, 'owner_desc': owner_desc, 'owner_website': owner_website})
CURRENT_WRAPPER = None


class Layout(Enum):
    """
    Base layout template to be inherited by an email-specific template.
    """
    SUBJECT = '/common/subject.j2'
    """
    Subject line of the email.
    """
    BODY = '/common/body.j2'
    """
    Main content of the email.
    """


class EmailWrapper:
    """
    Context manager for email sending, used to augment emails with additional metadata.
    """

    def __init__(self, subject: str=None, body: str=None, context: dict=None):
        self._layouts = {Layout.SUBJECT: subject, Layout.BODY: body}
        self._context = context

    def render(self, template: str, layout: Layout, target: Owner, context:
        dict=None):
        """
        Render an email template with Jinja using the provided context.
        """
        context = dict(context or (), layout=layout.value, target=target)
        out = ENV.get_template(template).render(context)
        custom = self._layouts.get(layout)
        if custom:
            if self._context:
                context.update(self._context)
            out = custom.format(out, **context)
        if layout == Layout.SUBJECT:
            out = ' '.join(out.split())
        return out

    def __enter__(self):
        global CURRENT_WRAPPER
        if CURRENT_WRAPPER:
            raise RuntimeError('Another context is already active')
        CURRENT_WRAPPER = self

    def __exit__(self, exception_type, exception_value, traceback):
        global CURRENT_WRAPPER
        CURRENT_WRAPPER = None


DEFAULT_WRAPPER = EmailWrapper(subject='[SRCF] {}')


def send(target: Owner, template: str, context: dict=None, session:
    SQLA_SESSION=None):
    """
    Render and send an email to the target member or society.
    """
    wrapper = CURRENT_WRAPPER or DEFAULT_WRAPPER
    subject = wrapper.render(template, Layout.SUBJECT, target, context)
    body = wrapper.render(template, Layout.BODY, target, context)
    recipient = owner_desc(target, True), target.email
    send_mail(recipient, subject, body, copy_sysadmins=False, session=session)

"""
Notification email machinery, for tasks to send credentials and instructions to users.

Email templates placed inside the `templates` directory of this module should:

- extend from `layout`
- provide `subject` and `body` blocks
"""

from enum import Enum
import os.path

from jinja2 import Environment, FileSystemLoader

from sqlalchemy.orm import Session as SQLA_SESSION

from srcf.database import Member, Society
from srcf.mail import send_mail

from ..plumbing import Owner, owner_desc, owner_name, owner_website


ENV = Environment(loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), "templates")),
                  trim_blocks=True, lstrip_blocks=True)

ENV.filters.update({"is_member": lambda mem: isinstance(mem, Member),
                    "is_society": lambda soc: isinstance(soc, Society),
                    "owner_name": owner_name,
                    "owner_desc": owner_desc,
                    "owner_website": owner_website})


CURRENT_WRAPPER = None


class Layout(Enum):
    """
    Base layout template to be inherited by an email-specific template.
    """

    SUBJECT = "/common/subject.j2"
    """
    Subject line of the email.
    """
    BODY = "/common/body.j2"
    """
    Main content of the email.
    """


class EmailWrapper:
    """
    Context manager for email sending, used to augment emails with additional metadata.
    """

    def __init__(self, subject: str=None, body: str=None, context: dict=None):
        self._layouts = {Layout.SUBJECT: subject,
                         Layout.BODY: body}
        self._context = context

    def render(self, template: str, layout: Layout, target: Owner, context: dict=None):
        """
        Render an email template with Jinja using the provided context.
        """
        context = dict(context or (), layout=layout.value, target=target)
        out = ENV.get_template(template).render(context)
        custom = self._layouts.get(layout)
        if custom:
            if self._context:
                context.update(self._context)
            out = custom.format(out, **context)
        if layout == Layout.SUBJECT:
            out = " ".join(out.split())
        return out

    def __enter__(self):
        global CURRENT_WRAPPER
        if CURRENT_WRAPPER:
            raise RuntimeError("Another context is already active")
        CURRENT_WRAPPER = self

    def __exit__(self, exception_type, exception_value, traceback):
        global CURRENT_WRAPPER
        CURRENT_WRAPPER = None


DEFAULT_WRAPPER = EmailWrapper(subject="[SRCF] {}")


def send(target: Owner, template: str, context: dict=None, session: SQLA_SESSION=None):
    """
    Render and send an email to the target member or society.
    """
    wrapper = CURRENT_WRAPPER or DEFAULT_WRAPPER
    subject = wrapper.render(template, Layout.SUBJECT, target, context)
    body = wrapper.render(template, Layout.BODY, target, context)
    recipient = (owner_desc(target, True), target.email)
    send_mail(recipient, subject, body, copy_sysadmins=False, session=session)
