# coding: utf-8

from pathlib import Path
from threading import Thread
from time import sleep

from .util import (BaseTestInterfaceProcessing, mock_filedialog,
                   mock_warning_window)


class Test12StopProcessImages(BaseTestInterfaceProcessing):

    def _stop_processing(self) -> None:
        """This method sets the _stop_event flag while the processing loop is
        running.

        It emulates a click on the "Stop Processing" button in the interface,
        which cannot be achieved in the particular conditions of unit testing.
        """

        sleep(1)
        self._window._stop_event.set()

    def testStopProcessImages(self) -> None:
        """This test checks that the image processing can be successfully
        interrupted by clicking on the "Stop Processing" button after it was
        started."""

        # The mock selection window returns the paths to three images to load
        mock_filedialog.file_name = [
            str(Path(__file__).parent / 'data' / f'image_{i}.jpg')
            for i in (1, 2, 3)]
        mock_warning_window.WarningWindow.value = 1
        self._window._select_images()

        # Stopping the regular processing Thread
        self._window._stop_thread = True
        sleep(2)
        # Instantiating a Thread that will stop the processing loop later on
        stop_thread = Thread(target=self._stop_thread)
        # Instantiating a Thread that will stop the image processing later on
        click_thread = Thread(target=self._stop_processing)

        # Checking that the image canvas is empty of nuclei
        self.assertEqual(len(self._window._image_canvas._nuclei), 0)
        self.assertEqual(self._window._image_canvas._nuclei.nuclei_in_count,
                         0)
        self.assertEqual(self._window._image_canvas._nuclei.nuclei_out_count,
                         0)
        # Checking that the files table is empty of nuclei and fibers
        for i in range(3):
            self.assertEqual(
                len(self._window._files_table.table_items.entries[i].nuclei),
                0)
            self.assertEqual((self._window._files_table.table_items.entries[i].
                              nuclei.nuclei_in_count), 0)
            self.assertEqual((self._window._files_table.table_items.entries[i].
                              nuclei.nuclei_out_count), 0)
            self.assertEqual(
                len(self._window._files_table.table_items.entries[i].fibers),
                0)
            self.assertEqual((self._window._files_table.table_items.entries[i].
                              fibers.area), 0)

        # Invoking the button for starting the image processing
        self._window._process_images_button.invoke()

        # Starting the Threads for later stopping the processing loop
        self._window._stop_thread = False
        stop_thread.start()
        click_thread.start()
        # Starting the processing loop in the main Thread rather than in a
        # separate one
        self._window._process_thread()

        # Checking that the image canvas is still empty of nuclei due to the
        # processing being interrupted
        self.assertEqual(len(self._window._image_canvas._nuclei), 0)
        self.assertEqual(self._window._image_canvas._nuclei.nuclei_in_count,
                         0)
        self.assertEqual(self._window._image_canvas._nuclei.nuclei_out_count,
                         0)

        # Checking that the files table is still empty of nuclei and fibers due
        # to the processing being interrupted
        for i in range(3):
            self.assertEqual(
                len(self._window._files_table.table_items.entries[i].nuclei),
                0)
            self.assertEqual((self._window._files_table.table_items.entries[i].
                              nuclei.nuclei_in_count), 0)
            self.assertEqual((self._window._files_table.table_items.entries[i].
                              nuclei.nuclei_out_count), 0)
            self.assertEqual(
                len(self._window._files_table.table_items.entries[i].fibers),
                0)
            self.assertEqual((self._window._files_table.table_items.entries[i].
                              fibers.area), 0)
