#!/usr/share/ucs-test/runner /usr/share/ucs-test/selenium
# -*- coding: utf-8 -*-
## desc: Test changing the order of portal categories/entries from within the portal
## roles:
##  - domaincontroller_master
## tags:
##  - SKIP
##  - skip_admember
## join: true
## exposure: dangerous

import time
import logging
import json

from univention.testing import selenium
import univention.testing.ucr as ucr_test
from univention.testing.udm import UCSTestUDM
import univention.testing.strings as uts
from univention.admin import localization
from univention.udm import UDM
from univention.testing.selenium.utils import expand_path

logger = logging.getLogger(__name__)

translator = localization.translation('ucs-test-selenium')
_ = translator.translate


class UMCTester(object):

	def test_umc(self):
		try:
			self.init()
			self.do_test()
		finally:
			self.cleanup()

	def init(self):
		logger.info('Creating dummy portal entries and categories')
		self.entry_a_1_dname = "entry_a_1__{}".format(uts.random_string())
		entry_a_1_dn = self.udm_test.create_object(
			'portals/entry',
			name=self.entry_a_1_dname,
			displayName=['en_US ' + self.entry_a_1_dname],
			description=['en_US foo'],
			link=['en_US foo'],
		)
		self.entry_a_2_dname = "entry_a_2__{}".format(uts.random_string())
		entry_a_2_dn = self.udm_test.create_object(
			'portals/entry',
			name=self.entry_a_2_dname,
			displayName=['en_US ' + self.entry_a_2_dname],
			description=['en_US foo'],
			link=['en_US foo'],
		)
		self.cat_a_dname = "category_a__{}".format(uts.random_string())
		cat_a_dn = self.udm_test.create_object(
			'portals/category',
			name=self.cat_a_dname,
			displayName=['en_US ' + self.cat_a_dname],
			entries=[entry_a_1_dn, entry_a_2_dn],
		)
		self.entry_b_dname = "entry_b__{}".format(uts.random_string())
		entry_b_dn = self.udm_test.create_object(
			'portals/entry',
			name=self.entry_b_dname,
			displayName=['en_US ' + self.entry_b_dname],
			description=['en_US foo'],
			link=['en_US foo'],
		)
		self.cat_b_dname = "category_b__{}".format(uts.random_string())
		cat_b_dn = self.udm_test.create_object(
			'portals/category',
			name=self.cat_b_dname,
			displayName=['en_US ' + self.cat_b_dname],
			entries=[entry_b_dn],
		)

		logger.info('Creating dummy portal')
		self.dummy_portal_title = uts.random_string()
		self.dummy_portal_dn = self.udm_test.create_object(
			'portals/portal',
			name=uts.random_string(),
			displayName=['en_US ' + self.dummy_portal_title],
			categories=[cat_a_dn, cat_b_dn],
			portalComputers=[ucr.get('ldap/hostdn')],
		)

		logger.info('Saving previously set portalComputers of main portal')
		udm = UDM.admin().version(1)
		portal = udm.obj_by_dn('cn=domain,cn=portal,cn=portals,cn=univention,{}'.format(ucr.get('ldap/base')))
		self.prev_comps = portal.props.portalComputers
		portal.props.portalComputers = []
		portal.save()

	def do_test(self):
		self.selenium.do_login()

		logger.info('Visiting dummy portal')
		self.selenium.driver.get(self.selenium.base_url)
		self.selenium.wait_for_text(self.dummy_portal_title)

		logger.info('Enter edit mode')
		self.selenium.click_element(expand_path('//*[@containsClass="iconMenu"]'))
		self.selenium.click_button(_('Edit Portal'))

		self.selenium.wait_for_text('Add category')

		logger.info('Check order before dnd')
		# Category_B is after Category_A
		self.selenium.driver.find_element_by_xpath('//h2[text()="%s"]/following::h2[text()="%s"]' % (self.cat_a_dname, self.cat_b_dname))
		# Entry_A is in Category_A
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_1_dname)))
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_2_dname)))
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]/following::*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_1_dname, self.entry_a_2_dname)))
		# Entry_B is in Category_B
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_b_dname, self.entry_b_dname)))

		logger.info('Drag category b above category a')
		self.selenium.drag_and_drop(
			expand_path('//*[@containsClass="dojoDndHandle"][text()="%s"]' % (self.cat_b_dname)),
			expand_path('//*[@containsClass="dojoDndHandle"][text()="%s"]' % (self.cat_a_dname))
		)
		self.selenium.wait_for_text('Order saved')
		self.selenium.wait_for_text_to_disappear('Order saved')

		logger.info('Check order after category dnd')
		# Category_A is after Category_B
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following::h2[text()="%s"]' % (self.cat_b_dname, self.cat_a_dname)))
		# Entry_A is in Category_A
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_1_dname)))
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_2_dname)))
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]/following::*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_1_dname, self.entry_a_2_dname)))
		# Entry_B is in Category_B
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_b_dname, self.entry_b_dname)))

		# TODO dragging entries across categories does not work in selenium for some reason
		self.selenium.drag_and_drop(
			expand_path('//*[@containsClass="dojoDndItem"]//*[@containsClass="tile__name"][text()="%s"]' % (self.entry_a_1_dname)),
			expand_path('//*[@containsClass="dojoDndItem"]//*[@containsClass="tile__name"][text()="%s"]' % (self.entry_a_2_dname))
		)
		self.selenium.wait_for_text('Order saved')
		self.selenium.wait_for_text_to_disappear('Order saved')

		logger.info('Check order after entry dnd')
		# Category_A is after Category_B
		self.selenium.driver.find_element_by_xpath('//h2[text()="%s"]/following::h2[text()="%s"]' % (self.cat_b_dname, self.cat_a_dname))
		# Entry_A is in Category_A
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_1_dname)))
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_2_dname)))
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]/following::*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_2_dname, self.entry_a_1_dname)))
		# Entry_B is in Category_B
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_b_dname, self.entry_b_dname)))

		logger.info('Reload dummy portal')
		self.selenium.driver.get(self.selenium.base_url)
		self.selenium.wait_until_standby_animation_appears_and_disappears()

		logger.info('Check order after reload')
		# Category_A is after Category_B
		self.selenium.driver.find_element_by_xpath('//h2[text()="%s"]/following::h2[text()="%s"]' % (self.cat_b_dname, self.cat_a_dname))
		# Entry_A is in Category_A
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_1_dname)))
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_2_dname)))
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]/following::*[@containsClass="tile__name"][text()="%s"]' % (self.cat_a_dname, self.entry_a_2_dname, self.entry_a_1_dname)))
		# Entry_B is in Category_B
		self.selenium.driver.find_element_by_xpath(expand_path('//h2[text()="%s"]/following-sibling::*//*[@containsClass="tile__name"][text()="%s"]' % (self.cat_b_dname, self.entry_b_dname)))

	def cleanup(self):
		logger.info('Cleanup')
		if hasattr(self, 'prev_comps'):
			logger.info('Restore previously set portalComputers on main portal')
			udm = UDM.admin().version(1)
			portal = udm.obj_by_dn('cn=domain,cn=portal,cn=portals,cn=univention,{}'.format(ucr.get('ldap/base')))
			portal.props.portalComputers = self.prev_comps
			portal.save()


if __name__ == '__main__':
	with ucr_test.UCSTestConfigRegistry() as ucr, UCSTestUDM() as udm_test, selenium.UMCSeleniumTest(suppress_notifications=False) as s:
		umc_tester = UMCTester()
		umc_tester.ucr = ucr
		umc_tester.udm_test = udm_test
		umc_tester.selenium = s

		umc_tester.test_umc()
