from django.test import LiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait

from core.models import UserAccount
from util.factories import make_test_data
from functional_tests.util import create_browser, reset_browser_after_test


class LoginPageTest(LiveServerTestCase):
    browser: webdriver.Firefox = None

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.browser = create_browser()

    @classmethod
    def tearDownClass(cls):
        super().tearDownClass()
        cls.browser.quit()

    def setUp(self):
        self.test_data = make_test_data(data_dict={
            'submission_types': [
                {
                    'name': '01. Sort this or that',
                    'full_score': 35,
                    'description': 'Very complicated',
                    'solution': 'Trivial!'
                },
                {
                    'name': '02. Merge this or that or maybe even this',
                    'full_score': 35,
                    'description': 'Very complicated',
                    'solution': 'Trivial!'
                }
            ],
            'students': [
                {'username': 'student01', 'password': 'p'},
                {'username': 'student02', 'password': 'p'}
            ],
            'tutors': [
                {'username': 'tutor01', 'password': 'p'},
                {'username': 'tutor02', 'password': 'p'}
            ],
            'reviewers': [
                {'username': 'reviewer', 'password': 'p'}
            ],
            'submissions': [
                {
                    'text': 'function blabl\n'
                            '   on multi lines\n'
                            '       for blabla in bla:\n'
                            '           lorem ipsum und so\n',
                    'type': '01. Sort this or that',
                    'user': 'student01',
                    'feedback': {
                        'score': 5,
                        'is_final': True,
                        'feedback_lines': {
                            '1': [{
                                'text': 'This is very bad!',
                                'of_tutor': 'tutor01'
                            }],
                        }

                    }
                },
                {
                    'text': 'function blabl\n'
                            '       asasxasx\n'
                            '           lorem ipsum und so\n',
                    'type': '02. Merge this or that or maybe even this',
                    'user': 'student01'
                },
                {
                    'text': 'function blabl\n'
                            '   on multi lines\n'
                            '       asasxasx\n'
                            '           lorem ipsum und so\n',
                    'type': '01. Sort this or that',
                    'user': 'student02'
                },
                {
                    'text': 'function lorem ipsum etc\n',
                    'type': '02. Merge this or that or maybe even this',
                    'user': 'student02'
                },
            ]}
        )

    def tearDown(self):
        reset_browser_after_test(self.browser, self.live_server_url)

    def _login(self, account):
        self.browser.get(self.live_server_url)
        username_input = self.browser.find_element_by_xpath('//input[@aria-label="Username"]')
        username_input.send_keys(account.username)
        password_input = self.browser.find_element_by_xpath('//input[@aria-label="Password"]')
        password_input.send_keys('p')
        self.browser.find_element_by_xpath('//button[@type="submit"]').send_keys(Keys.ENTER)
        WebDriverWait(self.browser, 3).until(ec.url_contains('/home'))

    def test_tutor_can_login(self):
        tutor = self.test_data['tutors'][0]
        self._login(tutor)
        self.assertTrue(self.browser.current_url.endswith('#/home'))

    def test_reviewer_can_login(self):
        reviewer = self.test_data['reviewers'][0]
        self._login(reviewer)
        self.assertTrue(self.browser.current_url.endswith('#/home'))

    def test_student_can_login(self):
        student = self.test_data['students'][0]
        self._login(student)
        self.assertTrue(self.browser.current_url.endswith('#/home'))

    def test_can_register_account(self):
        username = 'danny'
        password = 'redrum-is-murder-reversed'
        self.browser.get(self.live_server_url)
        self.browser.find_element_by_id('register').click()
        self.browser.find_element_by_id('gdpr-notice')
        self.browser.find_element_by_id('accept-gdpr-notice').click()
        username_input = self.browser.find_element_by_id('input-register-username')
        username_input.send_keys(username)
        password_input = self.browser.find_element_by_id('input-register-password')
        password_input.send_keys(password)
        register_submit_el = self.browser.find_element_by_id('register-submit')
        register_submit_el.click()
        WebDriverWait(self.browser, 3).until_not(ec.visibility_of(register_submit_el))
        tutor = UserAccount.objects.get(username=username)
        self.assertEqual(UserAccount.TUTOR, tutor.role)
        self.assertFalse(tutor.is_active, "Tutors should be inactive after registered")