"""Test dialog in new_module_dialog.py."""

import unittest
from PySide2 import QtGui
from PySide2.QtGui import QIcon
from PySide2.QtWidgets import QApplication
from PySide2.QtCore import QTimer, Qt
from PySide2.QtTest import QTest
from soitool.new_module_dialog import NewModuleDialog
from soitool.modules.module_base import ModuleBase

# The error being ignored here is pylint telling us that 'test' is a standard
# module, so the import should be placed further up. In our case we have an
# actual custom module called 'test', so pylint is confused.
# pylint: disable=C0411
from test.test_accept_reject_dialog import dialog_code_test_helper


class SimpleTestModule(ModuleBase):
    """Simple module used to test NewModuleDialog only."""

    name = ""

    def set_pos(self, pos):
        """Not used."""
        raise NotImplementedError

    def render_onto_pdf(self):
        """Not used."""
        raise NotImplementedError

    def get_size(self):
        """Not used."""
        raise NotImplementedError

    @classmethod
    def get_user_friendly_name(cls):
        """Get placeholder name."""
        return cls.name

    @staticmethod
    def get_icon():
        """Get standard placeholder icon."""
        return QIcon("soitool/media/placeholder.png")


if isinstance(QtGui.qApp, type(None)):
    app = QApplication([])
else:
    app = QtGui.qApp


class TestNewModuleDialog(unittest.TestCase):
    """TestCase for NewModuleDialog class."""

    def test_starts_up(self):
        """Test that the dialog can start.

        Also tests whether dialog can be closed with the enter key.
        """
        dialog = NewModuleDialog()

        def assert_window_title_of_active_dialog():
            active_widget = app.activeModalWidget()
            self.assertEqual("Ny modul", active_widget.windowTitle())
            QTest.keyClick(active_widget, Qt.Key_Enter)

        QTimer.singleShot(0, assert_window_title_of_active_dialog)
        dialog.exec_()

    def test_dialog_code(self):
        """Test that the dialog returns dialog codes as expected."""
        # Makes use of helper function from other test case
        dialog_code_test_helper(self, NewModuleDialog)

    def test_full_selection_scenario(self):
        """Test full usage of the module."""
        TestModule1 = SimpleTestModule
        TestModule1.name = "test1"
        TestModule2 = SimpleTestModule
        TestModule2.name = "test2"
        module_choices = [TestModule1, TestModule2]

        module_to_choose = 1

        name_to_input = "myname"

        def perform_selection_and_add():
            """Perform selection and accept.

            Select second module, give name, check the attachment checkbox and
            click add.
            """
            # Below code is based on code written when we were learning Qt:
            # https://gitlab.stud.iie.ntnu.no/bachelor-paa-bittet/learning/blob/master/gui_nikko/test_widgets.py#L46
            active_widget = app.activeModalWidget()

            model_index = active_widget.list_module_choices.model().index(
                module_to_choose, 0
            )
            item_point = active_widget.list_module_choices.visualRect(
                model_index
            ).center()

            QTest.mouseClick(
                active_widget.list_module_choices.viewport(),
                Qt.LeftButton,
                Qt.NoModifier,
                item_point,
            )

            QTest.keyClicks(active_widget.line_edit_name, name_to_input)
            QTest.mouseClick(active_widget.checkbox_attachment, Qt.LeftButton)
            QTest.mouseClick(active_widget.button_ok, Qt.LeftButton)

        dialog = NewModuleDialog(module_choices=module_choices)
        QTimer.singleShot(0, perform_selection_and_add)
        dialog.exec()

        # Assert dialog was successfully filled

        self.assertEqual(
            name_to_input, dialog.line_edit_name.text(),
        )
        self.assertEqual(
            True, dialog.checkbox_attachment.isChecked(),
        )

        module_choice = dialog.list_module_choices.currentItem()
        self.assertEqual(
            module_choices[module_to_choose],
            module_choice.widget_implementation,
        )
        self.assertEqual(
            module_choices[module_to_choose].get_user_friendly_name(),
            module_choice.text(),
        )