#!/usr/share/ucs-test/runner python
## -*- coding: utf-8 -*-
## desc: test anonymization, blocking and static sync settings
## tags: [apptest]
## exposure: dangerous
## packages:
##   - univention-office365

import time

import univention.testing.ucr as ucr_test
import univention.testing.udm as udm_test
import univention.testing.strings as uts
import univention.testing.utils as utils
from univention.config_registry import handler_set, handler_unset

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


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")

			print("*** Setting UCRs...")
			roomNumber = uts.random_string()
			city = uts.random_string()
			to_unset = ["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/anonymize=givenName,street,postalCode",
				"office365/attributes/never=mail,postalCode",
				"office365/attributes/static/roomNumber={}".format(roomNumber),
				"office365/attributes/static/postalCode=12345",
				"office365/attributes/static/l={}".format(city),
				"office365/debug/werror=yes",
			])
			utils.restart_listener()

			user_args = udm_user_args(ucr, minimal=False)
			user_args["set"]["UniventionOffice365Enabled"] = 1

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

			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).")

			print("*** Checking sync of properties...")
			fake_listener_new = dict(
				entryUUID=[udm_user.dn],
				univentionOffice365ObjectID=[user_id]
			)
			azure_user = ol.get_user(fake_listener_new)
			success, errors = check_udm2azure_user(user_args, azure_user, complete=True)
			if success:
				utils.fail("UCRVs office365/attributes/{anonymize, static, never} were ignored.")

			print("*** Properties that differ to LDAP:\n{}".format("\n".join(map(str, errors))))

			# rewrite error dict and check that "sync errors" are as expected
			errors = dict([(udm_attr, val) for udm_attr, _, val in errors])

			#
			# never
			#
			for attrib in ["e-mail", "postcode"]:
				try:
					value = errors[attrib]
				except KeyError:
					utils.fail("Attribute '{}' is synced, but should not be.".format(attrib))
				if value is None:
					# postcode should be None
					pass
				elif isinstance(value, list):
					for val in value:
						if val in user_args["append"][attrib]:
							utils.fail("Attribute '{}' was synced, but should not be.".format(attrib))
						else:
							# e-mail will exist with entries from mailPrimaryAddress and mailAlternativeAddress,
							# but must not contain addresses from "mail" attribute
							pass
				else:
					utils.fail("Attribute '{}' was set, but should not be.".format(attrib))

			print("*** OK: office365/attributes/never")

			#
			# anonymize
			#
			for attrib in ["firstname", "street"]:
				try:
					value = errors[attrib]
				except KeyError:
					utils.fail("Attribute '{}' was synced without anonymizing it.".format(attrib))
				udm_val = user_args[attrib] if attrib in ["firstname", "lastname"] else user_args["set"][attrib]
				if udm_val == value:
					utils.fail("Attribute '{}' was synced without anonymizing it.".format(attrib))

			print("*** OK: office365/attributes/anonymize")

			#
			# static
			#
			for attrib in ["roomNumber", "city"]:
				try:
					value = errors[attrib]
				except KeyError:
					utils.fail("Attribute '{}' was synced without anonymizing it.".format(attrib))
				if user_args["set"][attrib] == value:
					utils.fail("Attribute '{}' was synced without anonymizing it.".format(attrib))

			print("*** OK: office365/attributes/static")
