#  Copyright (C) 2021
#  ABM, Moscow
#
#  UNPUBLISHED PROPRIETARY MATERIAL.
#  ALL RIGHTS RESERVED.
#
#  Authors: Vasya Svintsov <v.svintsov@techokert.ru>

import logging
from dataclasses import dataclass
from typing import Union, List, Optional

from botocore.exceptions import ClientError
from http_tools.attached_file import AttachedFile


from .amazon_ses_connector import AmazonSESConnector
from ..email_client import EmailClient
from ...sending_result import SendingResult

from ...tools.generate_email_message import generate_message


logger = logging.getLogger(__name__)


class AmazonSESEmailClient(EmailClient):
    @dataclass
    class Config(AmazonSESConnector.Config):
        ...

    def __init__(self, config: Config):
        self._ses_connector = AmazonSESConnector(config)

    async def send(self,
                   to_recipients: Union[str, List[str]],
                   subject: str,
                   body: str,
                   source_email_account: str,
                   *,
                   source_email_account_name: Optional[str] = None,
                   attachments: Optional[List[AttachedFile]] = None,
                   cc_recipients: Optional[Union[str, List[str]]] = None,
                   bcc_recipients: Optional[Union[str, List[str]]] = None
                   ) -> SendingResult:
        message = generate_message(source_email_account, to_recipients, subject, body,
                                   source_email_account_name=source_email_account_name,
                                   attachments=attachments,
                                   cc_recipients=cc_recipients,
                                   bcc_recipients=bcc_recipients)
        send_args = {
            'Source': message["From"],
            "RawMessage": {'Data': message.as_string()},
            'Destinations': [to_recipients] if not isinstance(to_recipients, list) else to_recipients
        }
        try:
            async with self._ses_connector.get_client_creator() as client_session:
                response = await client_session.send_raw_email(**send_args)
            message_id = response['MessageId']
            logger.info(f"Email({message_id}) sent from {source_email_account} to {to_recipients} successfully.")
            result = SendingResult(True, message_id)
        except ClientError as er:
            logger.error(f"Email sent from {source_email_account} to {to_recipients} failed, because {repr(er)}.")
            result = SendingResult(False)
        return result
