#!/usr/share/ucs-test/runner python
## -*- coding: utf-8 -*-
## desc: create and modify user in azure, check values usageLocation takes
## tags: [apptest]
## exposure: dangerous
## packages:
##   - univention-office365

import time
import random
from operator import itemgetter

import univention.testing.ucr as ucr_test
import univention.testing.udm as udm_test
import univention.testing.utils as utils
from univention.config_registry import handler_set, handler_unset
import univention.admin.syntax as udm_syntax

from helpers.office365_test_helpers import listener_attributes_data, udm_user_args, check_udm2azure_user
from univention.office365.listener import Office365Listener


blacklisted_ul = ["CU", "KP"]  # some usageLocations seem to be invalid, collecting them here
usage_locations = set(udm_syntax.Country.choices) - set(blacklisted_ul)


def _test(udm_args, a_user, check_complete):
	success, errors = check_udm2azure_user(udm_args, a_user, check_complete)
	if success:
		print("*** all attributes were synced correctly")
	else:
		utils.fail("One or more properties were not synced correctly:\n{}".format("\n".join(map(str, errors))))

with utils.AutomaticListenerRestart():
	with udm_test.UCSTestUDM() as udm:
		with ucr_test.UCSTestConfigRegistry() as ucr:
			ucr.load()
			class _listener(object):
				configRegistry = ucr
			ol = Office365Listener(_listener(), "ucs-test", listener_attributes_data, {}, "dn")

			ucr_usageLocation = random.choice(map(itemgetter(0), usage_locations))
			ucr_ssl_country = ucr["ssl/country"]
			user_args = udm_user_args(ucr, minimal=False)
			udm_country = user_args["set"]["country"]
			user_args["set"]["UniventionOffice365Enabled"] = 1

			print("*** Setting UCRs for maximum property sync...")
			to_unset = ["office365/attributes/anonymize", "office365/attributes/never",
				"office365/groups/sync", "office365/subscriptions/service_plan_names"]
			to_unset.extend([k.split("=")[0] for k, v in ucr.items() if k.startswith("office365/attributes/static/")])
			handler_unset(to_unset)
			handler_set([
				"office365/attributes/mapping/l=city",
				"office365/attributes/mapping/displayName=displayName",
				"office365/attributes/mapping/employeeType=jobTitle",
				"office365/attributes/mapping/givenName=givenName",
				"office365/attributes/mapping/mobile=mobile",
				"office365/attributes/mapping/mail=otherMails",
				"office365/attributes/mapping/mailAlternativeAddress=otherMails",
				"office365/attributes/mapping/mailPrimaryAddress=otherMails",
				"office365/attributes/mapping/postalCode=postalCode",
				"office365/attributes/mapping/roomNumber=physicalDeliveryOfficeName",
				"office365/attributes/mapping/st=usageLocation",
				"office365/attributes/mapping/street=streetAddress",
				"office365/attributes/mapping/sn=surname",
				"office365/attributes/mapping/telephoneNumber=telephoneNumber",
				"office365/attributes/sync=l,st,displayName,employeeType,givenName,mailPrimaryAddress,mobile,mailAlternativeAddress,mail,postalCode,roomNumber,st,street,sn,telephoneNumber",
				"office365/attributes/usageLocation={}".format(ucr_usageLocation),
				"office365/debug/werror=yes",
			])
			utils.restart_listener()

			print("*** Set office365/attributes/mapping/st=usageLocation")
			print("*** Set office365/attributes/usageLocation={}".format(ucr_usageLocation))
			print("*** Set user[set][country]={}".format(udm_country))

			print("*** Creating user with some properties...")
			user_dn, username = udm.create_user(check_for_drs_replication=True, **user_args)
			time.sleep(5)

			print("*** Checking that user was created (UniventionOffice365ObjectID in UDM object)...")
			udm_user = ol.udm.get_udm_user(user_dn)
			user_id = udm_user.get("UniventionOffice365ObjectID")
			if not user_id:
				utils.fail("User was not created properly (no UniventionOffice365ObjectID).")

			fake_listener_new = dict(
				entryUUID=[udm_user.dn],
				univentionOffice365ObjectID=[user_id]
			)

			print("*** Checking sync of all properties...")
			azure_user = ol.get_user(fake_listener_new)
			_test(user_args, azure_user, check_complete=True)

			print("*** Checking value of usageLocation (should be user[set][country] now)...")
			if not azure_user["usageLocation"] == udm_country:
				utils.fail("'usageLocation' was not set to LDAP property 'st' (is: {}, should be: {}).".format(
					azure_user["usageLocation"], udm_country))

			print("*** Unsetting UDM property 'country'...")
			udm.modify_object(
				modulename="users/user",
				dn=user_dn,
				set=dict(country=''),
			)
			time.sleep(5)

			print("*** Checking value of usageLocation (should be UCR[office365/attributes/usageLocation] now)...")
			azure_user = ol.get_user(fake_listener_new)
			if not azure_user["usageLocation"] == ucr_usageLocation:
				utils.fail("'usageLocation' was not set to UCRV (is: {}, should be: {}).".format(
					azure_user["usageLocation"], ucr_usageLocation))

			print("*** Unsetting UCRV office365/attributes/usageLocation...")
			handler_unset(["office365/attributes/usageLocation"])

			print("*** Setting property 'country' back to '{}'...".format(udm_country))
			udm.modify_object(
				modulename="users/user",
				dn=user_dn,
				set=dict(country=udm_country),
			)
			time.sleep(5)

			print("*** Checking value of usageLocation (should be user[set][country] now)...")
			azure_user = ol.get_user(fake_listener_new)
			if not azure_user["usageLocation"] == udm_country:
				utils.fail("'usageLocation' was not set as instructed (is: {}, should be: {}).".format(
					azure_user["usageLocation"], udm_country))

			print("*** Unsetting property 'country'...")
			udm.modify_object(
				modulename="users/user",
				dn=user_dn,
				set=dict(country=''),
			)
			time.sleep(5)

			print("*** Checking value of usageLocation (should be UCR[ssl/country] now)...")
			azure_user = ol.get_user(fake_listener_new)
			if not azure_user["usageLocation"] == ucr_ssl_country:
				utils.fail("'usageLocation' was not set to UCRV of 'ssl/country' (is: {}, should be: {}).".format(
					azure_user["usageLocation"], ucr_ssl_country))
