import unittest

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support import expected_conditions as EC
import os
import sys
import time

class TestMatomoWeb(unittest.TestCase):

    def checkTitle(self, title: str):
        try:
            self.assertIn("Matomo", self.driver.title)
            self.assertIn(title, self.driver.title)
        except AssertionError:
            print("Web page source:")
            print(self.driver.page_source)
            raise

    def setUp(self):
        self.data_dir = os.getenv('AUTOPKGTEST_TMP', default='/tmp') + '/google-chrome'

        # print('Using chrome data dir: ' + self.data_dir)

        options = webdriver.ChromeOptions()
        options.add_argument('--headless')
        options.add_argument('--no-sandbox')
        options.add_argument('--disable-gpu')
        options.add_argument('--disable-dev-shm-usage')
        options.add_argument('--profile-directory=Default')
        options.add_argument('--user-data-dir=' + self.data_dir)
        service = Service(executable_path=r'/usr/bin/chromedriver')
        self.driver = webdriver.Chrome(service=service, options=options)

    def tearDown(self):
        self.driver.close()

    def test_01_first_install_page(self):
        self.driver.get("http://localhost:8888/matomo/")
        self.checkTitle("Installation")

        WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//p[contains(text(), 'This process has 8 steps and takes around 5 minutes.')]")
        )

        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//a[contains(text(), 'Next')]"))

    def test_02_second_install_page(self):
        self.driver.get("http://localhost:8888/matomo/?action=systemCheck")
        self.checkTitle("Installation")

        WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//h2[contains(text(), 'System Check')]")
        )
        WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//td[contains(text(), 'Directories with write access')]")
        )
        WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//td[contains(text(), 'Matomo Version')]")
        )

        # Debug failures:
        # print(self.driver.execute_script("return document.body.innerHTML"))
        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//a[contains(text(), 'Next')]"))

    def test_03_db_install_pages(self):
        self.process_page_three_setup_db()
        self.process_page_four_tables_created()
        self.process_page_five_create_super_user()
        self.process_page_six_create_website()
        self.process_page_seven_website_created()
        self.process_page_eight_the_end()
        self.process_page_login()

    def process_page_three_setup_db(self):
        self.driver.get("http://localhost:8888/matomo/?action=databaseSetup")
        mariadb_socket = os.getenv('MARIADB_UNIX_SOCKET')
        self.assertTrue(
            os.path.exists(mariadb_socket),
            'The socket file %s does not exist' % mariadb_socket
        )
        self.assertIn("Matomo", self.driver.title)
        self.assertIn("Installation", self.driver.title)

        WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//h2[contains(text(), 'Database Setup')]")
        )
        WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//label[contains(text(), 'Table Prefix')]")
        )

        option_pdo = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//li/span[contains(text(), 'PDO\\MYSQL')]")
        )
        option_mariadb = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//li/span[contains(text(), 'MariaDB')]")
        )

        db_host = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "host-0")
        )
        db_host.clear()
        db_host.send_keys(mariadb_socket)

        db_user = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "username-0")
        )
        db_user.send_keys("matomo-user")

        db_pass = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "password-0")
        )
        db_pass.send_keys("MatomoP@ssw0rd")

        db_name = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "dbname-0")
        )
        db_name.send_keys("matomo-db")

        db_tbl_prefix = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "tables_prefix-0")
        )
        db_tbl_prefix.send_keys("matomo_%s" % time.strftime('%Y_%m_%d__%H_%M_%S'))

        driver_type = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "(//input[@class=\"select-dropdown dropdown-trigger\"])[1]")
        )
        driver_type.click()
        option_pdo.click()

        db_type = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "(//input[@class=\"select-dropdown dropdown-trigger\"])[2]")
        )
        db_type.click()
        option_mariadb.click()

        submit_db_step = WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//input[contains(@value, 'Next')]"))
        submit_db_step.click()

    def process_page_four_tables_created(self):
        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//h2[contains(text(), 'Creating the Tables')]"))

        WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//div[@class=\"alert alert-success\" and contains(text(), 'Tables created')]")
        )

        next_btn = WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//a[contains(text(), 'Next')]"))
        next_btn.click()

    def process_page_five_create_super_user(self):
        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//h2[contains(text(), 'Superuser')]"))

        matomo_user = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "login-0")
        )
        matomo_user.send_keys("matomo-superuser")

        db_pass = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "password-0")
        )
        db_pass.send_keys("MatomoFrontEndP@ss")

        db_pass = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "password_bis-0")
        )
        db_pass.send_keys("MatomoFrontEndP@ss")

        matomo_user_email = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "email-0")
        )
        matomo_user_email.send_keys("test@company.intranet")

        submit_user_step = WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//input[contains(@value, 'Next')]"))
        submit_user_step.click()

    def process_page_six_create_website(self):
        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//h2[contains(text(), 'Set up a Website')]"))

        WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//div[@class=\"alert alert-success\" and contains(text(), 'Superuser created.')]")
        )

        matomo_site_name = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "siteName-0")
        )
        matomo_site_name.send_keys("Intranet webpage")

        matomo_site_url = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "url-0")
        )
        matomo_site_url.clear()
        matomo_site_url.send_keys("http://dashboard.intranet")

        timezone = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "(//input[@class=\"select-dropdown dropdown-trigger\"])[1]")
        )
        timezone.click()

        option_fr = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//li/span[contains(text(), 'France')]")
        )
        self.driver.execute_script("arguments[0].scrollIntoView(true);", option_fr)
        option_fr.click()

        submit_website_step = WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//input[contains(@value, 'Next')]"))
        submit_website_step.click()

    def process_page_seven_website_created(self):
        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//h2[contains(text(), 'Tracking code for Intranet webpage')]"))
        WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//div[@class=\"alert alert-success\" and contains(text(), 'Intranet webpage website created')]")
        )
        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//h3[contains(text(), 'JavaScript Tracking Code')]"))

        submit_tracking_step = WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//a[contains(text(), 'Next')]"))
        submit_tracking_step.click()

    def process_page_eight_the_end(self):
        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//h2[contains(text(), 'Congratulations')]"))
        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//h3[contains(text(), 'Welcome to the Matomo community.')]"))

        submit_continue = WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//input[contains(@value, 'Continue to Matomo')]"))
        self.driver.execute_script("arguments[0].scrollIntoView(true);", submit_continue)
        submit_continue.click()

    def process_page_login(self):
        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//h2[contains(text(), 'Sign in')]"))
        WebDriverWait(self.driver, 60).until(lambda x: x.find_element(By.XPATH, "//a[@title=\"Lost your password?\"]"))

        matomo_username = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "login_form_login")
        )
        matomo_username.send_keys("matomo-superuser")

        matomo_password = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.ID, "login_form_password")
        )
        matomo_password.send_keys("MatomoFrontEndP@ss")

        submit_do_login = WebDriverWait(self.driver, 60).until(
            lambda x: x.find_element(By.XPATH, "//input[contains(@value, 'Sign in')]")
        )
        submit_do_login.click()

        WebDriverWait(self.driver, 120).until(lambda x: x.find_element(By.XPATH, "//h1[contains(text(), 'Choose your tracking method')]"))
        self.checkTitle("Intranet webpage - Web Analytics Reports - Matomo")

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(TestMatomoWeb)
    result = unittest.TextTestRunner(verbosity=2).run(suite)

    if not result.wasSuccessful():
        sys.exit(1)
