#!/usr/bin/env python3

import os
import subprocess
import sys
import time

if sys.platform == 'haiku1':
    print('Automation tests are disabled on Haiku.')
    exit(0)

from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait

def exists_in_shadow_root(shadow_root, by, value):
	return lambda driver: shadow_root.find_element(by, value)

success = False
try:
	options = webdriver.FirefoxOptions()
	service = Service(log_output = 'out/geckodriver.log')
	#options.add_argument('--headless')
	driver = webdriver.Firefox(options = options, service = service)
	wait = WebDriverWait(driver, 10)
	driver.get('http://localhost:8888')
	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.LINK_TEXT, 'login').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'register_label').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('testuser')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'confirm').send_keys('test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()

	wait.until(expected_conditions.presence_of_element_located((By.ID, 'document')))
	driver.switch_to.frame(driver.find_element(By.ID, 'document'))
	wait.until(expected_conditions.presence_of_element_located((By.LINK_TEXT, 'identity')))
	driver.switch_to.default_content()
	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.ID, 'create_identity').click()
	wait.until(expected_conditions.alert_is_present()).accept()

	driver.switch_to.frame(driver.find_element(By.ID, 'document'))
	wait.until(expected_conditions.presence_of_element_located((By.LINK_TEXT, 'identity'))).click()

	# StaleElementReferenceException
	while True:
		try:
			driver.switch_to.default_content()
			wait.until(expected_conditions.presence_of_element_located((By.ID, 'content')))
			driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))))
			wait.until(expected_conditions.presence_of_element_located((By.ID, 'create_id'))).click()
			driver.switch_to.alert.accept()
			break
		except:
			pass

	# StaleElementReferenceException
	while True:
		try:
			id0 = wait.until(expected_conditions.presence_of_element_located((By.TAG_NAME, 'li'))).text.split(' ')[-1]
			break
		except:
			pass
	wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//li/button[text()="Export Identity"]'))).click()
	driver.switch_to.default_content()
	wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//button[text()="✅ Allow"]'))).click()
	driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))))
	words = wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//li//textarea'))).get_attribute('value')
	wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//li/button[text()="Delete Identity"]'))).click()
	driver.switch_to.alert.send_keys('DELETE')
	driver.switch_to.alert.accept()
	driver.switch_to.default_content()
	wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//button[text()="✅ Allow"]'))).click()
	driver.switch_to.alert.accept()
	driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))))
	words = wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//textarea'))).send_keys(words)
	wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//button[text()="Import Identity"]'))).click()
	driver.switch_to.default_content()
	wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//button[text()="✅ Allow"]'))).click()
	driver.switch_to.alert.accept()
	driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))))
	id1 = wait.until(expected_conditions.presence_of_element_located((By.TAG_NAME, 'li'))).text.split(' ')[-1]

	driver.get('http://localhost:8888/~core/admin/')
	wait.until(expected_conditions.presence_of_element_located((By.ID, 'document')))
	driver.switch_to.frame(driver.find_element(By.ID, 'document'))
	wait.until(expected_conditions.presence_of_element_located((By.ID, 'gs_room_name'))).send_keys('test room')
	wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//*[@id="gs_room_name"]/following-sibling::button'))).click()
	driver.switch_to.alert.accept()

	driver.get('http://localhost:8888')
	wait.until(expected_conditions.presence_of_element_located((By.ID, 'document')))
	driver.switch_to.frame(driver.find_element(By.ID, 'document'))
	wait.until(expected_conditions.presence_of_element_located((By.LINK_TEXT, 'ssb'))).click()
	driver.switch_to.default_content()

	wait.until(expected_conditions.presence_of_element_located((By.ID, 'content')))

	# StaleElementReferenceException
	while True:
		try:
			driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))))
			break
		except:
			pass
	# NoSuchShadowRootException
	while True:
		try:
			tf_app = wait.until(expected_conditions.presence_of_element_located((By.TAG_NAME, 'tf-app'))).shadow_root
			break
		except:
			pass

	# WebDriverException (shadow root is detached)
	while True:
		try:
			tf_tab_news = wait.until(exists_in_shadow_root(tf_app, By.ID, 'tf-tab-news')).shadow_root
			tf_tab_news.find_element(By.ID, 'tf-compose').shadow_root.find_element(By.ID, 'edit').send_keys('Hello, world!')
			tf_tab_news.find_element(By.ID, 'tf-compose').shadow_root.find_element(By.ID, 'submit').click()
			break
		except:
			pass

	driver.switch_to.default_content()
	driver.find_element(By.ID, 'allow').click()

	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.ID, 'identity').click()
	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.ID, 'logout').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'login_label').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('testuser')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()

	wait.until(expected_conditions.presence_of_element_located((By.ID, 'content')))

	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.ID, 'identity').click()
	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.ID, 'logout').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'guest_label').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'guestButton').click()

	wait.until(expected_conditions.presence_of_element_located((By.ID, 'content')))
	driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))))
	wait.until(expected_conditions.presence_of_element_located((By.TAG_NAME, 'tf-app'))).shadow_root
	driver.switch_to.default_content()

	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.ID, 'logout').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'login_label').click()

	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('testuser')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('wrong_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'error')

	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('wrong_user')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'error')

	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'register_label').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('testuser')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('wrong_test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'confirm').send_keys('wrong_test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'error')

	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'register_label').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('1invalid')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'confirm').send_keys('test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'error')

	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'register_label').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('😁')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'confirm').send_keys('test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'error')

	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'change_label').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('testuser')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'new_password').send_keys('new_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'confirm').send_keys('new_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
	wait.until(expected_conditions.presence_of_element_located((By.ID, 'document')))
	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.ID, 'identity').click()
	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.ID, 'logout').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'login_label').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('testuser')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('test_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'error')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'login_label').click()
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('testuser')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('new_password')
	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
	wait.until(expected_conditions.presence_of_element_located((By.ID, 'document')))

	success = True
finally:
	driver.close()
	driver.quit()

if success:
	print('\033[92mTEST SUCCEEDED.\033[0m')
else:
	print('\033[91mTEST FAILED.\033[0m')