# Path: src/schemas/messages.py
# class EmailRecipientModel(BaseModel):
#     first_name: str = None
#     last_name: str = None
#     user_link: str = None
#     address: str = ...
#     tags: List[str] = []
#     context: dict = {}
#     headers: dict = {}
#     pdf_attachments: List[PDFAttachmentModel] = []
#     attachments: List[AttachmentModel] = []
# 
#     class Config:
#         max_anystr_length = int(1e7)
# 
# Path: src/worker/email.py
# STYLES_SASS = (THIS_DIR / 'extra' / 'default-styles.scss').read_text()
# def utcnow():
#     def __init__(self, ctx: dict, group_id: int, company_id: int, recipient: EmailRecipientModel, m: EmailSendModel):
#     async def run(self):
#     async def _send_mandrill(self, email_info: EmailInfo, attachments: List[dict]):
#     async def _send_test_email(self, email_info: EmailInfo, attachments: List[dict]):
#     async def _render_email(self, context, headers) -> Optional[EmailInfo]:
#     async def _generate_base64_pdf(self, pdf_attachments):
#     async def _generate_base64(self, attachments: List[AttachmentModel]):
#     async def _store_email(self, external_id, send_ts, email_info: EmailInfo):
#     async def _store_email_failed(self, status: MessageStatus, error_msg):
# async def send_email(ctx, group_id: int, company_id: int, recipient: EmailRecipientModel, m: EmailSendModel):
# class SendEmail:
# 
# Path: src/worker/scheduler.py
# async def delete_old_emails(ctx):
#     if not glove.settings.delete_old_emails:
#         logger.info('settings.delete_old_emails False, not running')
#         return
#     async with glove.pg.acquire() as conn:
#         count = await conn.execute_b(
#             'delete from message_groups where id in (select id from message_groups where created_ts < :cutoff)',
#             cutoff=datetime.now() - timedelta(days=365),
#         )
#     logger.info('deleted %s old messages', count.replace('DELETE ', ''))


import base64
import hashlib
import hmac
import json
import pytest
import re
from arq import Retry
from buildpg import V
from datetime import datetime, timedelta, timezone
from foxglove.db.helpers import SyncDb
from pathlib import Path
from pytest_toolbox.comparison import AnyInt, RegexStr
from starlette.testclient import TestClient
from uuid import uuid4
from src.schemas.messages import EmailRecipientModel
from src.worker import delete_old_emails, email_retrying, send_email as worker_send_email


def test_mandrill_send_bad_template(cli: TestClient, send_email, sync_db: SyncDb, dummy_server):
    assert sync_db.fetchval('select count(*) from messages') == 0
    send_email(
        method='email-mandrill', main_template='{{ foo } test message', recipients=[{'address': 'foobar_b@testing.com'}]
    )
    message = sync_db.fetchrow_b('select * from messages')
    assert message['status'] == 'render_failed'


def test_send_email_headers(cli: TestClient, tmpdir, worker, loop, dummy_server):
    uid = str(uuid4())
    data = {
        'uid': uid,
        'company_code': 'foobar',
        'from_address': 'Samuel <s@muelcolvin.com>',
        'method': 'email-test',
        'subject_template': 'test email {{ a }}',
        'context': {'message__render': 'test email {{ a }} {{ b}} {{ c }}.\n', 'a': 'Apple', 'b': 'Banana'},
        'headers': {'Reply-To': 'another@whoever.com', 'List-Unsubscribe': '<http://example.org/unsub>'},
        'recipients': [
            {'first_name': 'foo', 'last_name': 'bar', 'address': 'foobar@example.org', 'context': {'c': 'Carrot'}},
            {
                'address': '2@example.org',
                'context': {'b': 'Banker'},
                'headers': {'List-Unsubscribe': '<http://example.org/different>'},
            },
        ],
    }

# Path: src/schemas/messages.py
# class EmailRecipientModel(BaseModel):
#     first_name: str = None
#     last_name: str = None
#     user_link: str = None
#     address: str = ...
#     tags: List[str] = []
#     context: dict = {}
#     headers: dict = {}
#     pdf_attachments: List[PDFAttachmentModel] = []
#     attachments: List[AttachmentModel] = []
# 
#     class Config:
#         max_anystr_length = int(1e7)
# 
# Path: src/worker/email.py
# STYLES_SASS = (THIS_DIR / 'extra' / 'default-styles.scss').read_text()
# def utcnow():
#     def __init__(self, ctx: dict, group_id: int, company_id: int, recipient: EmailRecipientModel, m: EmailSendModel):
#     async def run(self):
#     async def _send_mandrill(self, email_info: EmailInfo, attachments: List[dict]):
#     async def _send_test_email(self, email_info: EmailInfo, attachments: List[dict]):
#     async def _render_email(self, context, headers) -> Optional[EmailInfo]:
#     async def _generate_base64_pdf(self, pdf_attachments):
#     async def _generate_base64(self, attachments: List[AttachmentModel]):
#     async def _store_email(self, external_id, send_ts, email_info: EmailInfo):
#     async def _store_email_failed(self, status: MessageStatus, error_msg):
# async def send_email(ctx, group_id: int, company_id: int, recipient: EmailRecipientModel, m: EmailSendModel):
# class SendEmail:
# 
# Path: src/worker/scheduler.py
# async def delete_old_emails(ctx):
#     if not glove.settings.delete_old_emails:
#         logger.info('settings.delete_old_emails False, not running')
#         return
#     async with glove.pg.acquire() as conn:
#         count = await conn.execute_b(
#             'delete from message_groups where id in (select id from message_groups where created_ts < :cutoff)',
#             cutoff=datetime.now() - timedelta(days=365),
#         )
#     logger.info('deleted %s old messages', count.replace('DELETE ', ''))


# Path: tests/test_email.py
import base64
import hashlib
import hmac
import json
import pytest
import re
from arq import Retry
from buildpg import V
from datetime import datetime, timedelta, timezone
from foxglove.db.helpers import SyncDb
from pathlib import Path
from pytest_toolbox.comparison import AnyInt, RegexStr
from starlette.testclient import TestClient
from uuid import uuid4
from src.schemas.messages import EmailRecipientModel
from src.worker import delete_old_emails, email_retrying, send_email as worker_send_email



def test_mandrill_send_bad_template(cli: TestClient, send_email, sync_db: SyncDb, dummy_server):
    assert sync_db.fetchval('select count(*) from messages') == 0
    send_email(
        method='email-mandrill', main_template='{{ foo } test message', recipients=[{'address': 'foobar_b@testing.com'}]
    )
    message = sync_db.fetchrow_b('select * from messages')
    assert message['status'] == 'render_failed'


def test_send_email_headers(cli: TestClient, tmpdir, worker, loop, dummy_server):
    uid = str(uuid4())
    data = {
        'uid': uid,
        'company_code': 'foobar',
        'from_address': 'Samuel <s@muelcolvin.com>',
        'method': 'email-test',
        'subject_template': 'test email {{ a }}',
        'context': {'message__render': 'test email {{ a }} {{ b}} {{ c }}.\n', 'a': 'Apple', 'b': 'Banana'},
        'headers': {'Reply-To': 'another@whoever.com', 'List-Unsubscribe': '<http://example.org/unsub>'},
        'recipients': [
            {'first_name': 'foo', 'last_name': 'bar', 'address': 'foobar@example.org', 'context': {'c': 'Carrot'}},
            {
                'address': '2@example.org',
                'context': {'b': 'Banker'},
                'headers': {'List-Unsubscribe': '<http://example.org/different>'},
            },
        ],
    }

    r = cli.post('/send/email/', json=data, headers={'Authorization': 'testing-key'})