from math import prod

import cv2
import pytest

from test.utils.utils import powerset


@pytest.mark.parametrize("background_color", [255, 220])
class TestFindPrimaryTextRegions:
    def test_blank_page_yields_no_figures(self, figure_detection_pipeline, background):
        results = figure_detection_pipeline(background)

        assert not list(results)

    @pytest.mark.parametrize("image_size", [(200, 200), (500, 500), (800, 800)])
    def test_page_without_text_yields_figures(self, figure_detection_pipeline, page_with_images, image_size):
        results = figure_detection_pipeline(page_with_images)
        result_figures_size = map(lambda x: (x.w, x.h), results)

        assert all([image_size[0] < res[0] and image_size[1] < res[1] for res in result_figures_size])

    @pytest.mark.parametrize("font_scale", [1, 1.5, 2])
    @pytest.mark.parametrize("font_style", [cv2.FONT_HERSHEY_SIMPLEX, cv2.FONT_HERSHEY_COMPLEX])
    @pytest.mark.parametrize("text_types", powerset(["body", "header", "caption"]))
    @pytest.mark.parametrize("error_tolerance", [0.025])
    def test_page_with_only_text_yields_no_figures(self, figure_detection_pipeline, page_with_text, error_tolerance):
        results = figure_detection_pipeline(page_with_text)

        result_figures_area = sum(map(lambda x: (x.w * x.h), results))
        page_area = prod(page_with_text.shape)
        error = result_figures_area / page_area

        assert error <= error_tolerance

    @pytest.mark.parametrize("image_size", [(200, 200), (500, 500), (800, 800)])
    @pytest.mark.parametrize("font_scale", [1, 1.5, 2])
    @pytest.mark.parametrize("font_style", [cv2.FONT_HERSHEY_SIMPLEX, cv2.FONT_HERSHEY_COMPLEX])
    @pytest.mark.parametrize("text_types", powerset(["body", "header", "caption"]))
    @pytest.mark.parametrize("error_tolerance", [0.9])
    def test_page_with_images_and_text_yields_only_figures(
        self,
        figure_detection_pipeline,
        page_with_images_and_text,
        image_size,
        error_tolerance,
    ):
        results = list(figure_detection_pipeline(page_with_images_and_text))

        result_figures_area = sum(map(lambda x: (x.w * x.h), results))
        expected_figure_area = prod(image_size)

        error = abs(result_figures_area - expected_figure_area) / expected_figure_area

        assert error <= error_tolerance
