from email.message import Message
from office365.runtime.compat import get_mime_type, message_as_bytes_or_string
from office365.runtime.http.http_method import HttpMethod
from office365.runtime.queries.batch import create_boundary
from office365.runtime.queries.client_query import ClientQuery


def _message_to_payload(message):
    """
    :type message: Message
    """
    lf = b"\n"
    crlf = b"\r\n"
    payload = message_as_bytes_or_string(message)
    lines = payload.split(lf)
    payload = bytes.join(crlf, lines[2:]) + crlf
    return payload


class OneNotePageCreateQuery(ClientQuery):

    def __init__(self, pages, presentation_file, attachment_files=None):
        """
        :type pages: office365.onenote.pages.page_collection.OnenotePageCollection
        :type presentation_file: typing.IO
        :type attachment_files: dict or None
        """
        super(OneNotePageCreateQuery, self).__init__(pages.context, pages)
        pages.context.before_execute(self._construct_multipart_request)
        self._presentation = presentation_file
        if attachment_files is None:
            attachment_files = {}
        self._files = attachment_files

    def _construct_multipart_request(self, request):
        """
        :type request: office365.runtime.http.request_options.RequestOptions
        """
        request.method = HttpMethod.Post
        boundary = create_boundary("PageBoundary", True)
        request.set_header("Content-Type", "multipart/form-data; boundary={0}".format(boundary))

        main_message = Message()
        main_message.add_header("Content-Type", "multipart/form-data; boundary={0}".format(boundary))
        main_message.set_boundary(boundary)

        c_type, enc = get_mime_type(self._presentation.name)
        presentation_message = Message()
        presentation_message.add_header("Content-Type", c_type)
        presentation_message.add_header("Content-Disposition", "form-data; name=\"Presentation\"")
        presentation_message.set_payload(self._presentation.read())
        main_message.attach(presentation_message)

        for name, file in self._files.items():
            file_message = Message()
            c_type, enc = get_mime_type(file.name)
            file_message.add_header("Content-Type", c_type)
            file_message.add_header("Content-Disposition", "form-data; name=\"{0}\"".format(name))
            file_content = file.read()
            file_message.set_payload(file_content)
            main_message.attach(file_message)

        request.data = _message_to_payload(main_message)

    @property
    def return_type(self):
        if self._return_type is None:
            from office365.onenote.pages.page import OnenotePage
            self._return_type = OnenotePage(self.context)
            self.binding_type.add_child(self._return_type)
        return self._return_type
