# encoding: utf-8

"""Unit test suite for docx.image.jpeg module"""

from __future__ import absolute_import, print_function

import pytest

from docx.compat import BytesIO
from docx.image.constants import JPEG_MARKER_CODE, MIME_TYPE
from docx.image.helpers import BIG_ENDIAN, StreamReader
from docx.image.jpeg import (
    _App0Marker,
    _App1Marker,
    Exif,
    Jfif,
    _JfifMarkers,
    Jpeg,
    _Marker,
    _MarkerFactory,
    _MarkerFinder,
    _MarkerParser,
    _SofMarker,
)
from docx.image.tiff import Tiff

from ..unitutil.mock import (
    ANY,
    call,
    class_mock,
    initializer_mock,
    instance_mock,
    method_mock,
)


class DescribeJpeg(object):

    def it_knows_its_content_type(self):
        jpeg = Jpeg(None, None, None, None)
        assert jpeg.content_type == MIME_TYPE.JPEG

    def it_knows_its_default_ext(self):
        jpeg = Jpeg(None, None, None, None)
        assert jpeg.default_ext == 'jpg'

    class DescribeExif(object):

        def it_can_construct_from_an_exif_stream(self, from_exif_fixture):
            # fixture ----------------------
            stream_, _JfifMarkers_, cx, cy, horz_dpi, vert_dpi = (
                from_exif_fixture
            )
            # exercise ---------------------
            exif = Exif.from_stream(stream_)
            # verify -----------------------
            _JfifMarkers_.from_stream.assert_called_once_with(stream_)
            assert isinstance(exif, Exif)
            assert exif.px_width == cx
            assert exif.px_height == cy
            assert exif.horz_dpi == horz_dpi
            assert exif.vert_dpi == vert_dpi

    class DescribeJfif(object):

        def it_can_construct_from_a_jfif_stream(self, from_jfif_fixture):
            stream_, _JfifMarkers_, cx, cy, horz_dpi, vert_dpi = (
                from_jfif_fixture
            )
            jfif = Jfif.from_stream(stream_)
            _JfifMarkers_.from_stream.assert_called_once_with(stream_)
            assert isinstance(jfif, Jfif)
            assert jfif.px_width == cx
            assert jfif.px_height == cy
            assert jfif.horz_dpi == horz_dpi
            assert jfif.vert_dpi == vert_dpi

    # fixtures -------------------------------------------------------

    @pytest.fixture
    def from_exif_fixture(self, stream_, _JfifMarkers_, jfif_markers_):
        px_width, px_height = 111, 222
        horz_dpi, vert_dpi = 333, 444
        jfif_markers_.sof.px_width = px_width
        jfif_markers_.sof.px_height = px_height
        jfif_markers_.app1.horz_dpi = horz_dpi
        jfif_markers_.app1.vert_dpi = vert_dpi
        return (
            stream_, _JfifMarkers_, px_width, px_height, horz_dpi, vert_dpi
        )

    @pytest.fixture
    def from_jfif_fixture(self, stream_, _JfifMarkers_, jfif_markers_):
        px_width, px_height = 111, 222
        horz_dpi, vert_dpi = 333, 444
        jfif_markers_.sof.px_width = px_width
        jfif_markers_.sof.px_height = px_height
        jfif_markers_.app0.horz_dpi = horz_dpi
        jfif_markers_.app0.vert_dpi = vert_dpi
        return (
            stream_, _JfifMarkers_, px_width, px_height, horz_dpi, vert_dpi
        )

    @pytest.fixture
    def _JfifMarkers_(self, request, jfif_markers_):
        _JfifMarkers_ = class_mock(request, 'docx.image.jpeg._JfifMarkers')
        _JfifMarkers_.from_stream.return_value = jfif_markers_
        return _JfifMarkers_

    @pytest.fixture
    def jfif_markers_(self, request):
        return instance_mock(request, _JfifMarkers)

    @pytest.fixture
    def stream_(self, request):
        return instance_mock(request, BytesIO)