#!/usr/share/ucs-test/runner python3
# -*- coding: utf-8 -*-
## desc: Rename a container/cn with subobjects from lower to upper case
## tags: [udm]
## roles: [domaincontroller_master]
## exposure: careful
## packages:
##   - univention-config
##   - univention-directory-manager-tools


import univention.testing.utils as utils
import univention.testing.udm as udm_test
import univention.testing.strings as uts
import univention.config_registry as configRegistry
import ldap.dn
import ldap.filter

if __name__ == '__main__':
	ucr = configRegistry.ConfigRegistry()
	ucr.load()

	if utils.package_installed('univention-s4-connector'):
		# this test is not stable with the s4-connector
		# somehow we end up with
		#
		# Creating container/cn object with /usr/sbin/udm-test container/cn create --position dc=four,dc=four --set 'name=ĝkn}_>ä%\6'
		# Waiting for connector replication
		# Modifying container/cn object with /usr/sbin/udm-test container/cn modify --dn 'cn=ĝkn}_\>ä%\\6,dc=four,dc=four' --set 'name=ĝKN}_>ä%\6'
		# modrdn detected: 'cn=\xc4\x9dkn}_\\>\xc3\xa4%\\\\6,dc=four,dc=four' ==> 'cn=\xc4\x9dKN}_\\>\xc3\xa4%\\\\6,dc=four,dc=four'
		# Waiting for connector replication
		# ### FAIL ###
		# #cn = ĝkn}_>ä%\6; expected: ĝKN}_>ä%\6
		import sys
		from univention.testing.codes import TestCodes
		sys.exit(TestCodes.RESULT_SKIP)

	with udm_test.UCSTestUDM() as udm:
		def test_container(parent, add_user):
			if parent is None:
				parent = ucr.get('ldap/base')
			user_name = 'X' + uts.random_string()  # test preserving name (case sensitivity)

			cn_name = uts.random_name_special_characters()
			cn_name_new = cn_name.upper()

			cn = udm.create_object('container/cn', position=parent, name=cn_name)
			if add_user:
				udm.create_user(position=cn, username=user_name)

			try:
				udm.modify_object('container/cn', dn=cn, name=cn_name_new)
			except AssertionError:
				pass
			lo = utils.get_ldap_connection()
			fail = False
			for dn, entry in lo.search(filter='ou=temporary_move_container_*'):
				to_be_removed = udm._cleanup.setdefault('container/ou', [])
				to_be_removed.append(dn)
				fail = True
			if fail:
				utils.fail('ou = %s remained' % dn)

			new_cn = 'cn=%s,%s' % (ldap.dn.escape_dn_chars(cn_name_new), parent)
			new_user = 'uid=%s,%s' % (ldap.dn.escape_dn_chars(user_name), new_cn)

			utils.verify_ldap_object(new_cn, should_exist=True)
			if add_user:
				for dn, entry in lo.search(filter=ldap.filter.filter_format('uid=%s', [user_name])):
					if entry.get('uid')[0] != user_name.encode('UTF-8'):
						utils.fail('CASE SENSITIVITY: uid = %s; expected: %s' % (entry.get('uid')[0], user_name))
				utils.verify_ldap_object(new_user, should_exist=True)

			for dn, entry in lo.search(filter=ldap.filter.filter_format('cn=%s', [cn_name_new])):
				if entry.get('cn')[0] != cn_name_new.encode('UTF-8'):
					utils.fail('cn = %s; expected: %s' % (entry.get('cn')[0], cn_name_new))
			return new_cn

		# EMPTY
		# FIRST LEVEL
		first_level_container = test_container(parent=None, add_user=False)

		# SECOND LEVEL
		test_container(parent=first_level_container, add_user=False)

		# WITH USER
		# FIRST LEVEL
		first_level_container = test_container(parent=None, add_user=True)

		# SECOND LEVEL
		test_container(parent=first_level_container, add_user=True)
